Às vezes, um algoritmo pode ser escrito de duas maneiras:
- O caminho curto e chique; ou
- A maneira mais longa e fácil de entender.
Por exemplo, aqui está uma maneira mais longa e fácil de copiar uma string source
para dest
C:
*dest = *source;
while (*source != '\0') {
source++;
dest++;
*dest = *source;
} (true);
E aqui está uma maneira curta e chique.
// Copy string source to dest
while (*dest++ = *source++);
Eu sempre ouvi e li que códigos sofisticados devem ser evitados, e costumo concordar. Mas e se levarmos em conta os comentários? Suponha que, como nos exemplos acima, tenhamos um código não comentado, mais longo e supostamente mais fácil de entender, e um código bem comentado, curto e sofisticado? O código não sofisticado ainda é o preferido?
Edição: Muitos comentaram sobre nomes de variáveis, então eu modifiquei o código de exemplo para não tornar isso um fator ao preferir sobre o outro. Tentei remover a atribuição dupla no primeiro exemplo, mas isso apenas tornou o código menos legível.
Talvez este não tenha sido o melhor dos exemplos, porque muitos acham o código "sofisticado" mais legível e compreensível que o código mais longo. A idéia era ter um código mais longo que fosse muito mais fácil de entender do que um código muito curto, mas complicado.
EDIT2: Aqui está um novo exame que recebi da SO :
Versão chique comentada:
//direct formula for xoring all numbers from 1 to N
int Sum = (N & (N % 2 ? 0 : ~0) | ( ((N & 2)>>1) ^ (N & 1) ) );
Versão longa não comentada:
int Sum = 0;
for (int i = 1; i < N; ++i)
{
Sum ^= i; //or Sum = Sum ^ i;
}
Respostas:
Eu geralmente preferiria extrair o código sofisticado em seu próprio método ..
Em vez de comentar o código sofisticado, o nome do método deve ser tudo o que precisa para deixar as coisas claras.
fonte
Sou a favor da versão mais longa. O problema com a versão curta do código, além de ser mais difícil para alguns programadores de ler, é que na maioria das vezes é mais difícil detectar erros apenas olhando para ele.
Eu tenho um exemplo da vida real. Em nosso produto, tivemos o seguinte trecho de código:
Esse código parece perfeitamente razoável à primeira vista, mas após um longo período de tempo, esse contador transborda e quebra a condição (no cenário da vida real, esmagamos o sistema de produção de nossos clientes com uma OOM). Esse código é um pouco menos "sofisticado", mas é claro que ele faz o que deve fazer:
E você pode dizer que o desenvolvedor que escreveu esse código simplesmente não era bom o suficiente (o que não é verdade, ele era um cara bastante inteligente), mas acho que se sua técnica de codificação exigir que você seja um super habilidoso programador de DEUS em Para obter seu código correto, você está fazendo algo errado. Seu código deve ser o mais à prova de idiotas possível para você e para quem tiver que manter esse código depois de você (que pode não ser tão inteligente quanto você).
Então - sou a favor da simplicidade e clareza.
Edit: Ah, e sobre comentários - não importa. Muitas pessoas não lêem comentários de qualquer maneira ( http://www.javaspecialists.co.za/archive/Issue039.html ) e aqueles que não entenderão seu código sem comentários, não o entenderão suficientemente bem para que possam pode mantê-lo. O objetivo é ajudar as pessoas a ver que determinado código está "correto", os comentários não podem ajudar com isso.
fonte
Eu geralmente preferiria a versão mais longa. Duas razões principais vêm à mente:
Para o melhor dos dois mundos, envolva o código em uma função, cujo nome faz o comentário para você:
A única razão para não fazer isso seria se o desempenho fosse um problema e os perfis mostrassem genuinamente que a sobrecarga da função era significativa.
fonte
O que for mais claro. Muitas vezes, é um trecho de código compacto e fácil de entender que não requer comentários ... como o seu segundo exemplo.
Geralmente, trechos mais curtos de código são mais fáceis de entender, pois há menos para o leitor manter em mente por vez. Obviamente, há um limite quando o código fica ofuscado demais e não quero dizer que o espaço em branco que aprimora a clareza deve ser aparado.
Os comentários nunca devem declarar nada óbvio no código, que apenas faça o leitor ler a mesma coisa duas vezes. Para mim, o primeiro trecho exige esclarecimentos. Por que o desenvolvedor não usou um
do...while
loop para remover a duplicação da*s = *t;
tarefa? Eu tenho que analisar mais código para perceber que está implementando uma cópia de seqüência de caracteres. Um comentário seria mais útil nesse código mais longo do que no código mais curto.O comentário no segundo trecho é quase redundante, já que o loop while é praticamente idiomático, mas diz o que o código faz em um nível superior ao do próprio código, o que o torna um comentário útil.
fonte
do ... while
simplesmente porque não pensei nisso quando escrevi a pergunta. Obrigado por apontar isso. ^^ O segundo trecho pode ser óbvio para você, mas certamente não é para mim.O problema é que não há uma definição clara,
short fancy code
pois depende muito do nível do programador. Enquanto algumas pessoas não têm problemas para entender umawhile(*s++ = *t++);
expressão, outras o fazem .Pessoalmente, acho o mais
while(*s++ = *t++);
legível e o mais difícil de ler. Outros podem não concordar.Independentemente disso, é apenas uma questão de usar o bom senso. A legibilidade deve ser definitivamente uma prioridade, mas há um ponto em que um código mais longo fica menos legível quando mais longo. A verbosidade geralmente reduz a legibilidade da minha experiência.
fonte
Eu tenho que discordar da maioria das outras respostas aqui - acho que (pelo menos nesse caso) o código mais curto é melhor. Contrariamente à sua reivindicação, o código mais longo não é "mais fácil", pelo menos para um leitor. De qualquer forma, parece que você deixou de desejar prolongá-lo, mesmo que isso torne o código mais difícil de entender e / ou tenha certeza da operação correta.
Em particular, ter a atribuição do primeiro byte da string fora do loop, separada da atribuição para os outros bytes, significa que é preciso ter muito mais cuidado na leitura para garantir que todos os bytes sejam copiados corretamente. A sequência básica de ações na versão mais curta é muito mais fácil de verificar. Seu único problema real está na formatação - quando você tem um corpo de loop intencionalmente vazio, é melhor deixar isso claro, algo como:
ou até:
Algumas pessoas preferem usar aparelhos:
Independentemente da formatação exata de sua preferência, erros suficientes foram cometidos com coisas como:
... que é importante ter certeza de que 1) é óbvio o que é realmente controlado por qualquer controle de fluxo e 2) é óbvio que o código foi escrito sabendo o que foi controlado por ele, para que alguém que o leia não perca tempo tentando para descobrir se eles acabaram de encontrar um bug.
fonte
Certifique-se de que qualquer outro programador possa entender o que seu código faz - e melhor ainda, se for de relance (é aqui que bons nomes e comentários se encaixam).
O kung-fu extravagante e a montagem embutida são ótimos em nome da otimização (talvez desnecessária e prematura), mas quando você nem consegue entender o código que escreveu quando se depara com um bug dois meses depois .. Qual era o objetivo? Você vai gastar tempo e esforço.
Costumo me referir ao Zen de Python nessas situações. Em particular:
fonte
Não escreva código sofisticado no software de produção. Eu sei que é bom poder escrever isso, e é mais curto. Escrever código sofisticado aumenta significativamente o valor "WTF / minuto", ou seja, diminui a qualidade.
fonte
É claro que depende inteiramente das circunstâncias. mas, em geral, acho que essa é uma boa regra geral:
~ Brian Kernighan
fonte
Na minha experiência, a maior vitória em termos de códigos extravagantes curtos tende a usar recursão do que iteração. É também uma das coisas mais difíceis de entender em um relance de código, a menos que você esteja trabalhando no tipo de linguagem em que tudo é recursivo de qualquer maneira. Eu ainda o favoreceria pela elegância e velocidade de desenvolvimento que oferece, mas tento garantir que ele tenha comentários detalhados, se parecer que será opaco para futuros mantenedores ou para o meu eu futuro.
fonte
Estou começando a nunca confiar em comentários. Com muita frequência, os comentários não são atualizados quando o código é atualizado e estão muito desatualizados ou representam regras de clientes / gerenciamento que não são mais relevantes.
Chegou ao ponto em alguns casos em que os comentários nem sequer correspondem ao código que estão descrevendo mais.
Se eu tiver que escolher entre curto / extravagante e mais longo / mais fácil de entender, sempre escolho o último, a menos que haja um motivo realmente bom.
fonte
A legibilidade e a manutenção são essenciais, e seu segundo exemplo (ou seja, o mais longo) é muito mais dos dois. Mas por que se limitar a duas opções? Mesmo o código mais longo é muito complexo (IMHO) para não anotar mais. Eu o colocaria em um método próprio com Javadoc apropriado (ou o que seja) e um nome de método adequado.
fonte