ti-enxame.com

Código curto e sofisticado comentado versus código mais longo e fácil de entender - qual é o preferido?

Às vezes, um algoritmo pode ser escrito de duas maneiras:

  • O jeito 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 em C:

*dest = *source;
while (*source != '\0') {
    source++;
    dest++;
    *dest = *source;
} (true);

E aqui está uma maneira curta e sofisticada.

// Copy string source to dest
while (*dest++ = *source++);

Sempre ouvi e li que códigos sofisticados devem ser evitados e tendo a concordar. Mas e se levarmos os comentários em consideração? Suponha que, como nos exemplos acima, temos 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 é preferido?

EDITAR: 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 do que o código mais longo. A ideia 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 exemplo que recebi de ENTÃO :

Versão extravagante 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;
}
18
gablin

Eu geralmente prefiro extrair o código sofisticado em seu próprio método.

Em vez de comentar o código sofisticado, seu nome de método deve ser tudo o que precisa para deixar as coisas claras.

char *copy_string(char *s, const char *t) {    
    while (*s++ = *t++); 
    return s;
}
28
Mongus Pong

Sou totalmente 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 lerem, é que na maioria das vezes é mais difícil detectar erros apenas olhando para ele.

Eu tenho um exemplo da vida real. Em nosso produto, tínhamos o seguinte snippet de código:

if (++someCounter < MAX_VALUE) {
    // Do something that has to be done only MAX_VALUE times
}

Este código parece perfeitamente razoável à primeira vista, mas depois de 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 nosso cliente com um OOM). Este código é um pouco menos "sofisticado", mas está claro que faz o que deve fazer:

if (someCounter < MAX_VALUE) {
    ++someCounter;
    // Do whatever it is we came here for
}

E você pode dizer que o desenvolvedor que escreveu este código simplesmente não era bom o suficiente (o que não é verdade, ele era um cara bastante inteligente), mas eu acho que se sua técnica de codificação requer que você seja super-habilidoso em programação, GOD em para obter o código correto, você está fazendo algo errado. Seu código deve ser o mais infalível possível para o seu bem e para quem quer que tenha que manter esse código depois de você (que pode não ser tão inteligente quanto você).

Então - eu sou totalmente a favor da simplicidade e clareza.

Editar: Ah, e com relação aos comentários - não importa. Muitas pessoas não lerão os 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 bem o suficiente com eles para que possam mantê-lo. O objetivo é ajudar as pessoas a ver que determinado código está "correto", comentários não podem ajudar nisso.

10
Hila

Eu geralmente prefiro a versão mais longa. Duas razões principais vêm à mente:

  • É provável que mais pessoas entendam com menos esforço (assumindo que não seja um exemplo "padrão" como esta cópia da string).
  • É possível colocar pontos de interrupção em instruções individuais e avançar com um depurador.

Para o melhor dos dois mundos, envolva o código em uma função, cujo nome faz os comentários para você:

void copy_string(char *s, char *t)
{
    *s = *t;
    while (*t != '\0') {
        t++;
        s++;
        *s = *t;
    }
}

A única razão para não fazer isso seria se o desempenho fosse um problema e a criação de perfil mostrasse genuinamente que a sobrecarga da função era significativa.

6
Paul Stephenson

O que for mais claro. Freqüentemente, é um trecho de código compacto e fácil de entender que não requer um comentário ... como o seu segundo exemplo.

Geralmente, trechos de código mais curtos são mais fáceis de entender, pois há menos para o leitor manter em sua cabeça por vez. Obviamente, há um limite quando o código fica excessivamente ofuscado e não quero dizer que o espaço em branco que aumenta a clareza deva ser cortado.

Os comentários nunca devem declarar nada que seja óbvio no código, que apenas faça o leitor ler a mesma coisa duas vezes. Para mim, o primeiro fragmento requer esclarecimento. Por que o desenvolvedor não usou um do...while loop para remover o duplicado do *s = *t; tarefa? Tenho que analisar mais código para perceber que ele está implementando uma cópia da string. Um comentário seria mais útil neste código mais longo do que no código mais curto.

O comentário no segundo fragmento é quase redundante, já que o loop while é praticamente idiomático, mas diz o que o código faz em um nível mais alto que o próprio código, o que o torna um comentário útil.

4
CB Bailey

O problema é que não existe uma definição clara de short fancy code, Pois depende muito do nível do programador. Enquanto algumas pessoas não têm problemas em entender uma expressão while(*s++ = *t++);, outras terão.

Pessoalmente, acho o while(*s++ = *t++); perfeitamente legível e o mais longo 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 o código mais longo fica menos legível quando fica mais longo. A verbosidade freqüentemente reduz a legibilidade da minha experiência.

4
Wolph
Keep it simple, stupid!

Certifique-se de que qualquer outro programador possa entender o que seu código faz - e ainda melhor se for de relance (é aqui que os bons nomes e comentários aparecem).

Kung-fu sofisticado e assembly embutido são ótimos em nome da otimização (talvez desnecessária e prematura), mas quando você não consegue entender o código você escreveu quando você se depara com um bug nele dois meses depois ... Qual era o ponto? Você vai se custar tempo e esforço.

Costumo me referir ao Zen do Python nessas situações. Em particular:

Explicit is better than implicit.
Simple is better than complex.
2
Humphrey Bogart

Tenho que discordar da maioria das outras respostas aqui - acho (pelo menos neste caso) o código mais curto é melhor. Ao contrário do que você afirma, o código mais longo é não "mais fácil", pelo menos para um leitor. No mínimo, parece que você saiu da vontade de torná-lo mais longo, mesmo que isso torne o código mais difícil de entender e/ou tenha certeza de operação correta.

Em particular, ter a atribuição do primeiro byte da string fora do loop, separada da atribuição dos outros bytes, significa que se deve ser muito mais cuidado na leitura para ter certeza de que todos os bytes são 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 é a formatação - quando você tem um corpo de loop intencionalmente vazio, é melhor deixar isso claro, algo como:

while (*dest++ = *source++)
    ;

ou mesmo:

while (*dest++ = *source++)
    ; /* no body */

Algumas pessoas preferem usar colchetes:

while (*dest++ = *source++)
    {}

Independentemente da formatação exata de sua preferência, erros suficientes foram cometidos com coisas como:

if (x>y);
     x = z;

... 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, então alguém lendo não perde tempo tentando descobrir se eles acabaram de encontrar um bug.

2
Jerry Coffin

Claro que depende inteiramente das circunstâncias. mas, em geral, acho que esta é uma boa regra prática:

Depurar é duas vezes mais difícil do que escrever o código em primeiro lugar. Portanto, se você escrever o código da forma mais inteligente possível, você, por definição, não será inteligente o suficiente para depurá-lo.

~ Brian Kernighan

1
violet313

Não escreva código sofisticado em software de produção. Eu sei que é bom poder escrever isso, e é mais curto. Escrever código sofisticado aumenta significativamente o valor "WTF/minuto", em outras palavras, diminui a qualidade.

alt text

1
Tamás Szelei

Estou começando a nunca confiar nos comentários. Freqüentemente, os comentários não são atualizados quando o código é atualizado e ficam muito desatualizados ou representam regras de clientes/gerenciamento que não são mais relevantes.

Em alguns casos, chegou ao ponto em que os comentários nem correspondem mais ao código que estão descrevendo.

Se eu tiver que escolher entre curto/sofisticado e mais longo/mais fácil de entender, então sempre escolho o último, a menos que haja um realmente bom motivo.

0
Steven Evers

Legibilidade e manutenção são fundamentais, e seu segundo exemplo (ou seja, o mais longo) é muito mais de ambos. Mas por que se limitar a duas opções? Mesmo o código mais longo é muito complexo (IMHO) para não fazer anotações adicionais. Eu o colocaria em um método próprio com Javadoc apropriado (ou qualquer outro) e um nome de método adequado.

0
Chris Knight

Na minha experiência, a maior vitória em termos de código curto e sofisticado tende a ser o uso de recursão em vez de iteração. É também uma das coisas mais difíceis de entender com uma rápida olhada no código, a menos que você esteja trabalhando em um 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 me certificar de que ele tenha comentários detalhados se parecer que será opaco para futuros mantenedores ou para mim.

0
glenatron