Sou um pouco novo em programação (sou engenheiro mecânico de profissão) e estou desenvolvendo um pequeno programa durante meu tempo de inatividade que gera uma peça (solidworks) com base nas informações de várias pessoas de toda a planta.
Com base em apenas algumas entradas (6 para ser exato), preciso fazer centenas de chamadas de API que podem levar até uma dúzia de parâmetros cada; tudo gerado por um conjunto de regras que reuni após entrevistar todos que lidam com a parte. A seção de regras e parâmetros do meu código tem 250 linhas e está crescendo.
Então, qual é a melhor maneira de manter meu código legível e gerenciável? Como compartimentalizo todos os meus números mágicos, todas as regras, algoritmos e partes processuais do código? Como faço para lidar com uma API muito detalhada e granular?
Meu principal objetivo é poder entregar a alguém a minha fonte e fazer com que ela entenda o que eu estava fazendo, sem a minha contribuição.
fonte
Respostas:
Com base no que você descreve, você provavelmente vai querer explorar o maravilhoso mundo dos bancos de dados. Parece que muitos dos números mágicos que você descreve - principalmente se dependem de parte - são realmente dados, não código. Você terá muito mais sorte e achará muito mais fácil estender o aplicativo a longo prazo, se puder categorizar como os dados se relacionam com as partes e definir uma estrutura de banco de dados para ele.
Lembre-se de que 'bancos de dados' não significam necessariamente MySQL ou MS-SQL. Como você armazena os dados dependerá muito de como o programa é usado, como você está gravando etc. Isso pode significar um banco de dados do tipo SQL ou simplesmente um arquivo de texto formatado.
fonte
A menos que você preveja estender isso para várias partes, eu relutaria em adicionar um banco de dados ainda. Ter um banco de dados significa uma grande pilha de coisas para aprender e mais coisas para instalar para que funcione para outras pessoas. Adicionar um banco de dados incorporado mantém o executável final portátil, mas alguém com seu código-fonte agora tem mais uma coisa para começar a trabalhar.
Eu acho que uma lista de constantes claramente nomeadas e funções de implementação de regras ajudará muito. Se você der nomes naturais a tudo e se concentrar nas técnicas de programação alfabetizada, poderá criar um programa legível.
Idealmente, você terminará com o código que diz:
Dependendo de quão local são as constantes, ficaria tentado a declará-las nas funções em que são usadas sempre que possível. É bastante útil ativar:
para dentro
Isso fornece um código amplamente auto-documentado e também incentiva qualquer pessoa que modifica o código a atribuir nomes com significado semelhante ao que eles adicionam. Iniciar localmente também facilita lidar com o número total de constantes que você acumulará. Fica um pouco chato se você precisar continuar percorrendo uma longa lista de constantes para garantir que o valor seja o desejado.
Uma dica para nomes: coloque a palavra mais importante à esquerda. Pode não ser tão bom assim, mas facilita encontrar as coisas. Na maioria das vezes, você está olhando para um poço e se perguntando sobre o parafuso, sem olhar para um parafuso e se perguntando onde ele funciona. Então, chame-o de SumpBoltThreadPitch e não BoltThreadPitchSump. Em seguida, classifique a lista de constantes. Posteriormente, para extrair todos os arremessos de encadeamento, você pode obter a lista em um editor de texto e usar a função find ou usar uma ferramenta como grep para retornar somente as linhas que contêm "ThreadPitch".
fonte
.CreateLine(m_trunion_support_spacing / 2, -((m_flask_length / 2) + m_sand_ledge_width + m_wall_thickness), -m_flange_thickness, m_trunion_support_spacing / 2, -((m_flask_length / 2) + m_sand_ledge_width + m_wall_thickness), -m_flask_height + m_flange_thickness)
createGroove(length, depth)
. Você precisa implementar funções que descrevam o que você deseja realizar como as descreveria a um engenheiro mecânico. É disso que trata a programação alfabetizada.Acho que sua pergunta se reduz a: como estruturar uma computação?Observe que você deseja gerenciar "um conjunto de regras", que são códigos, e "um conjunto de números mágicos", que são dados. (Você pode vê-los como "dados incorporados no seu código", mas, no entanto, são dados).
Além disso, tornar seu código "compreensível para os outros" é, de fato, o objetivo geral de todos os paradigmas de programação (veja, por exemplo, " Padrões de Implementação ", de Kent Beck, ou " Código Limpo ", de Robert C. Martin, para autores de software que afirmam o mesmo objetivo. como você, para qualquer programa).
Todas as dicas contidas nesses livros se aplicam à sua pergunta. Deixe-me extrair algumas dicas especificamente para "números mágicos" e "conjuntos de regras":
Use constantes nomeadas e enumerações para substituir números mágicos
Exemplo de constantes :
deve ser substituído por uma constante nomeada para que nenhuma alteração posterior possa introduzir um erro de digitação e quebrar seu código, por exemplo, alterando a primeira,
0.625
mas não a segunda.Exemplo de enumerações :
As enumerações podem ajudá-lo a reunir dados que pertencem um ao outro. Se você estiver usando Java, lembre-se de que as enums são objetos; seus elementos podem conter dados e você pode definir métodos que retornam todos os elementos ou verificar alguma propriedade. Aqui um Enum é usado na construção de outro Enum:
A vantagem é que agora ninguém pode definir erroneamente um EnginePart que não seja feito de aço ou carbono e ninguém pode introduzir um EnginePart chamado "asdfasdf", como seria o caso se fosse uma string que seria verificada no conteúdo.
O padrão de estratégia e o padrão de método de fábrica descrevem como encapsular "regras" e passá-las para outro objeto que as utilize (no caso do padrão de fábrica, o uso está criando algo; no caso do padrão de estratégia, o uso é o que você quiser).
Exemplo de padrão de método de fábrica :
Imagine que você tem dois tipos de motores: um em que cada parte deve ser conectada ao compressor e outro em que cada parte pode ser conectada livremente a quaisquer outras partes. Adaptado da Wikipedia
E então em outra aula:
A parte interessante é: agora o construtor AssemblyLine está separado do tipo de mecanismo que ele está manipulando. Talvez os
addEngine
métodos estejam chamando uma API remota ...Exemplo de padrão de estratégia :
O padrão Estratégia descreve como introduzir uma função em um objeto para alterar seu comportamento. Vamos imaginar que às vezes você queira polir uma peça, às vezes deseje pintá-la e, por padrão, deseja revisar sua qualidade. Este é um exemplo de Python, adaptado do Stack Overflow
Você pode expandir isso para manter uma lista de ações que deseja executar e, em seguida, chamá-las a partir do
execute
método. Talvez essa generalização possa ser melhor descrita como um padrão do Builder , mas, ei, não queremos ser exigentes, queremos? :)fonte
Você pode querer usar um mecanismo de regras. Um mecanismo de regras fornece uma DSL (Linguagem Específica de Domínio) projetada para modelar os critérios necessários para um determinado resultado de uma maneira compreensível, conforme explicado nesta pergunta .
Dependendo da implementação do mecanismo de regras, as regras podem até ser alteradas sem recompilar o código. E como as regras são escritas em linguagem própria e simples, elas também podem ser alteradas pelos usuários.
Se você tiver sorte, existe um mecanismo de regras pronto para uso para a linguagem de programação que você está usando.
A desvantagem é que você precisa se familiarizar com um mecanismo de regras que pode ser difícil se você é iniciante em programação.
fonte
Minha solução para esse problema é bem diferente: camadas, configurações e LOP.
Primeiro, envolva a API em uma camada. Encontre sequências de chamadas de API usadas em conjunto e combine-as com suas próprias chamadas de API. Eventualmente, não deve haver chamadas diretas para a API subjacente, apenas chamadas para seus wrappers. As chamadas do wrapper devem começar a parecer um mini idioma.
Segundo, implemente um 'gerenciador de configurações'. Essa é uma maneira de associar nomes a valores dinamicamente. Algo assim. Outra mini linguagem.
Por fim, implemente sua própria mini linguagem para expressar designs (isso é Programação Orientada a Idioma). Esse idioma deve ser compreensível para os engenheiros e designers que contribuem com as regras e configurações. O primeiro exemplo desse produto que vem à mente é o Gnuplot, mas existem muitos outros. Você poderia usar Python, embora pessoalmente eu não.
Entendo que essa é uma abordagem complexa e pode ser um exagero para o seu problema ou exigir habilidades que você ainda não adquiriu. É assim que eu faria.
fonte
Não tenho certeza se entendi a pergunta corretamente, mas parece que você deve agrupar as coisas em algumas estruturas. Digamos que se você estiver usando C ++, você pode definir coisas como:
Você pode instanciar estes no início do programa:
Em seguida, suas chamadas à API terão a aparência (supondo que você não possa alterar a assinatura):
Se você pode alterar a assinatura da API, pode passar toda a estrutura:
Você também pode agrupar todos os parâmetros em um invólucro maior:
fonte
Estou surpreso que ninguém mais tenha mencionado isso ...
Você disse:
Então deixe-me dizer isso, a maioria das outras respostas está no caminho certo. Eu definitivamente acho que os bancos de dados podem ajudá-lo. Mas outra coisa que o ajudará é comentar, bons nomes de variáveis e organização / separação apropriada de preocupações.
Todas as outras respostas são altamente técnicas, mas estão ignorando os fundamentos aprendidos pela maioria dos programadores. Como você é um engenheiro mecânico por profissão, acho que você não está acostumado a esse estilo de documentação.
Comentar e escolher nomes de variáveis bons e sucintos ajuda imensamente com a legibilidade. O que é mais fácil de entender?
Ou:
Isso é bastante independente da linguagem. Independentemente de qual plataforma, IDE, idioma etc. você esteja trabalhando, a documentação adequada é a maneira mais limpa e fácil de garantir que alguém possa entender seu código.
Em seguida, vamos gerenciar esses números mágicos e toneladas de preocupações, mas acho que o comentário do GrandmasterB lidou com isso muito bem.
fonte