Minimize os efeitos colaterais (o ideal é não ter nenhum)
Uma função que causa três alterações nos estados fora de seu próprio escopo é muito mais difícil de raciocinar e manter do que aquela que apenas insere algo e gera outra coisa. Você não pode apenas saber o que a função faz, é preciso lembrar o que ela fez e como isso afeta todas as outras funções relevantes.
Para OOP, minimizar efeitos colaterais também significa classes com menos membros e, especialmente, menos membros que podem modificar o estado da classe, uma vez que as funções de membro podem modificar estados além dos seus e causar efeitos colaterais (eles podem manipular os elementos internos da classe, por exemplo). Isso também significa classes com menos membros de dados próprios, para que haja menos estado para esses métodos adulterarem e menos efeitos colaterais que eles podem causar.
Como um exemplo simples, imagine tentar projetar uma estrutura de dados sofisticada que possa manter um sorted
estado usado para determinar se é necessário executar pesquisas binárias ou lineares. Nesse caso, pode ser útil separar o design em duas classes. Chamar sorted
a classe não classificada pode retornar uma estrutura de dados de outra classe que sempre mantém seu conteúdo classificado. Agora você tem menos efeitos colaterais (portanto, menos propenso a erros e mais fácil de entender o código), bem como um código mais amplamente aplicável (o design anterior seria um desperdício tanto no processamento quanto na eficiência intelectual humana para pequenas matrizes que nunca precisam ser classificadas).
Evitar dependências externas supérfluas
Você pode implementar o código mais conciso que se possa imaginar com a reutilização máxima de código usando 13 bibliotecas diferentes para realizar uma tarefa relativamente simples. No entanto, isso transfere sobrecarga intelectual para os seus leitores, fazendo com que eles entendam pelo menos partes de 13 bibliotecas diferentes. Essa complexidade inerente deve ser imediatamente apreciada por qualquer pessoa que tente criar e compreender uma biblioteca de terceiros que exija a instalação e a construção de uma dúzia de outras bibliotecas para funcionar.
Esta é provavelmente uma visão muito controversa, mas eu preferiria uma duplicação modesta de código ao extremo oposto, desde que o resultado final seja bem testado (nada pior do que um código defeituoso não testado duplicado várias vezes). Se a opção for entre três linhas de código duplicado para calcular um produto cruzado de vetor ou puxar uma biblioteca de matemática épica apenas para cortar três linhas de código, eu sugeriria o primeiro, a menos que toda a sua equipe esteja presente nessa biblioteca de matemática , nesse ponto, você ainda pode escrever apenas 3 linhas de código em vez de 1, se isso for trivial o suficiente em troca dos benefícios da dissociação.
A reutilização de código é um ato de equilíbrio. Reutilize demais e você transfere a complexidade intelectual de um modo para muitos, pois nessas três linhas de código simples que você salvou acima têm o custo de exigir que os leitores e mantenedores compreendam muito mais informações do que três linhas de código . Isso também torna seu código menos estável, pois, se a biblioteca de matemática mudar, o código também pode mudar. Reutilize muito pouco e você também multiplica a sobrecarga intelectual e seu código deixa de se beneficiar de melhorias centrais; portanto, é um ato de equilíbrio, mas vale a pena mencionar a idéia de que é um ato de equilíbrio, já que tentar eliminar todas as formas pequenas de duplicação modesta pode levar para um resultado que é tão difícil de manter, se não mais, do que o extremo oposto.
Teste sua porcaria
Isso é óbvio, mas se o seu código não trata de todos os casos de entrada e perde alguns casos extremos, como você pode esperar que outros mantenham o código que você escreveu e que nem acertou antes de ser transferido para os olhos e as mãos deles? Já é bastante difícil fazer alterações no código que funcione perfeitamente e muito menos em um código que nunca foi totalmente correto.
Além disso, o código que passa em testes completos geralmente encontra menos razões para mudar. Isso se refere à estabilidade, que é ainda mais um Santo Graal a ser alcançada do que a capacidade de manutenção, uma vez que o código estável que nunca precisa ser alterado não incorre em nenhum custo de manutenção.
Documentação da interface
Priorize "o que as coisas fazem" em vez de "como as coisas as fazem" se você não puder dedicar tempo igual à documentação de ambas. Uma interface clara que seja óbvia em suas intenções sobre o que fará (ou, pelo menos, o que deveria fazer) em todos os possíveis casos de entrada, trará uma clareza de contexto à sua própria implementação, o que guiará o entendimento não apenas de como para usar o código, mas também como ele funciona.
Enquanto isso, o código que não possui essas qualidades em que as pessoas nem sabem o que deve fazer é o SOL, independentemente de quão bem documentados sejam seus detalhes de implementação. Um manual de 20 páginas sobre como o código-fonte é implementado é inútil para as pessoas que nem conseguem descobrir exatamente como ele deve ser usado em primeiro lugar e o que ele deve fazer em todos os cenários possíveis.
Para o lado da implementação, priorize a documentação do que você faz de maneira diferente de todos os outros. Como exemplo, a Intel tem uma hierarquia de volume delimitadora para seus kernels de rastreamento de raios. Como trabalho neste campo, posso reconhecer rapidamente a maior parte do que o código está fazendo sem examinar a documentação. No entanto, eles fazem algo único, que é a idéia de atravessar o BVH e realizar interseções em paralelo usando pacotes de raios . É aí que eu quero que eles priorizem sua documentação, porque essas partes do código são exóticas e incomuns da maioria das implementações históricas do BVH.
Legibilidade
Esta parte é muito subjetiva. Eu realmente não me importo muito com a legibilidade de um tipo que se aproxime dos processos de pensamento humano. O código mais bem documentado que descreve as coisas no nível mais alto ainda é difícil de ser seguido se o autor usar processos de pensamento bizarros e complicados para resolver um problema. Enquanto isso, código conciso usando nomes de 2 ou 3 caracteres geralmente pode ser mais fácil para mim entender se a lógica é muito direta. Eu acho que você pode revisar e ver o que as outras pessoas preferem.
Estou interessado principalmente em manutenção e, mais importante ainda, estabilidade. O código que não encontra motivos para alterar é aquele que tem zero custo de manutenção.