O que há de errado com comentários que explicam código complexo?

231

Muitas pessoas afirmam que "os comentários devem explicar 'por que', mas não 'como'". Outros dizem que "o código deve ser auto-documentado" e os comentários devem ser escassos. Robert C. Martin afirma que (reescrito às minhas próprias palavras) muitas vezes "comentários são desculpas por código mal escrito".

Minha pergunta é a seguinte:

O que há de errado em explicar um algoritmo complexo ou uma parte longa e complicada do código com um comentário descritivo?

Dessa forma, em vez de outros desenvolvedores (incluindo você) terem que ler o algoritmo inteiro linha por linha para descobrir o que ele faz, eles podem apenas ler o comentário descritivo amigável que você escreveu em inglês simples.

O inglês é 'projetado' para ser facilmente entendido pelos humanos. Java, Ruby ou Perl, no entanto, foram projetados para balancear a legibilidade humana e a legibilidade do computador, comprometendo assim a legibilidade humana do texto. Um humano pode entender um pedaço de inglês muito mais rápido que ele / ela pode entender um pedaço de código com o mesmo significado (contanto que a operação não seja trivial).

Então, depois de escrever um pedaço complexo de código escrito em uma linguagem de programação parcialmente legível por humanos, por que não adicionar um comentário descritivo e conciso explicando o funcionamento do código em inglês amigável e compreensível?

Alguns dirão que "código não deve ser difícil de entender", "tornar funções pequenas", "usar nomes descritivos", "não escrever código de espaguete".

Mas todos sabemos que não é suficiente. Estas são meras diretrizes - importantes e úteis -, mas não mudam o fato de que alguns algoritmos são complexos. E, portanto, são difíceis de entender ao lê-los linha por linha.

É realmente tão ruim explicar um algoritmo complexo com algumas linhas de comentários sobre sua operação geral? O que há de errado em explicar código complicado com um comentário?

    
por Aviv Cohn 01.09.2014 / 02:28
fonte

16 respostas

402

Em termos leigos:

  • Não há nada errado com os comentários em si.
  • O que está errado é escrever código que precise desse tipo de comentário.
  • O que está errado é supor que está tudo bem escrever um código complicado, contanto que você o explique em inglês simples.
  • Os comentários não são atualizados automaticamente quando você altera o código. É por isso que muitas vezes os comentários não estão sincronizados com o código.
  • Os comentários não facilitam o teste do código.
  • Pedir desculpas não é ruim. O que você fez que requer pedir desculpas é ruim.
  • Um programador capaz de escrever código simples para resolver um problema complexo é melhor que um que escreve código complexo e depois escreve um longo comentário explicando o que seu código faz.

Resumindo:

Explicar a si mesmo é bom, não é necessário fazer isso.

    
por 01.09.2014 / 02:52
fonte
109

Há várias razões diferentes para que o código seja complicado ou confuso. As razões mais comuns são melhor abordadas refatorando o código para torná-lo menos confuso, não adicionando comentários de qualquer tipo.

No entanto, há casos em que um comentário bem escolhido é a melhor escolha.

  • Se é o próprio algoritmo que é complicado e confuso, não apenas sua implementação - o tipo que é escrito em revistas de matemática e é sempre referido como Algoritmo de Mbogo - então você coloca um comentário no início da implementação, lendo algo como "Este é o algoritmo de Mbogo para criar widgets, originalmente descrito aqui: [URL do papel]. Esta implementação contém refinamentos por Alice e Carol [URL de outro artigo]." Não tente entrar em mais detalhes do que isso; se alguém precisar de mais detalhes, provavelmente precisará ler o artigo inteiro.

  • Se você tomou algo que pode ser escrito como uma ou duas linhas em alguma notação especializada e expandiu-o em um grande código imperativo, colocar uma ou duas linhas de notação especializada em um comentário acima da função é uma boa maneira de dizer ao leitor o que é suposto fazer. Isso é uma exceção ao argumento "mas e se o comentário ficar fora de sincronia com o código", porque a notação especializada é provavelmente muito mais fácil de encontrar erros do que o código. (É o contrário se você escreveu uma especificação em inglês). Um bom exemplo está aqui: link ...

    /**
     * Scan a unicode-range token.  These match the regular expression
     *
     *     u\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?
     *
     * However, some such tokens are "invalid".  There are three valid forms:
     *
     *     u+[0-9a-f]{x}              1 <= x <= 6
     *     u+[0-9a-f]{x}\?{y}         1 <= x+y <= 6
     *     u+[0-9a-f]{x}-[0-9a-f]{y}  1 <= x <= 6, 1 <= y <= 6
    
  • Se o código é simples no geral, mas contém uma ou duas coisas que parecem excessivamente complicadas, desnecessárias ou simplesmente erradas, mas tem que ser assim por causa de razões, então você coloca um comentário imediatamente acima do bit suspeito, no qual você declara as razões . Aqui está um exemplo simples, onde a única coisa que precisa ser explicada é por que uma constante tem um certo valor.

    /* s1*s2 <= SIZE_MAX if s1 < K and s2 < K, where K = sqrt(SIZE_MAX+1) */
    const size_t MUL_NO_OVERFLOW = ((size_t)1) << (sizeof(size_t) * 4);
    if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
        nmemb > 0 && SIZE_MAX / nmemb < size)
      abort();
    
por 01.09.2014 / 04:35
fonte
61

So what's wrong with explaining complicated code with a comment?

Não é uma questão de certo ou errado, mas da "melhor prática", conforme definido no artigo da Wikipedia :

A best practice is a method or technique that has consistently shown results superior to those achieved with other means, and that is used as a benchmark.

Portanto, a melhor prática é tentar melhorar o código primeiro e usar o inglês se isso não for possível.

Não é uma lei, mas é muito mais comum encontrar um código com comentário que requeira refatoração do que o código refatorado que exige comentários. A melhor prática reflete isso.

    
por 01.09.2014 / 03:25
fonte
52

Chegará o dia em que seu código bonito, perfeitamente trabalhado, bem estruturado e legível não funcionará. Ou não funcionará bem o suficiente. Ou um caso especial surgirá quando não funcionar e precisar de ajustes.

Nesse ponto, você precisará fazer algo que altere as coisas para que funcione corretamente. Particularmente no caso em que há problemas de desempenho, mas também em cenários em que uma das bibliotecas, APIs, serviços da Web, gemas ou sistemas operacionais com os quais você está trabalhando não se comporta como esperado, você pode acabam fazendo sugestões que não são necessariamente deselegantes, mas são contra-intuitivas ou não óbvias.

Se você não tem alguns comentários para explicar por que você escolheu essa abordagem, há uma boa chance de que alguém no futuro (e que alguém possa até ser você) analise o código, veja como isso poderia ser " corrigido "para algo mais legível e elegante e, inadvertidamente, desfazer sua correção, porque não parece uma correção.

Se todo mundo sempre escrevesse código perfeito, então seria óbvio que o código que parece imperfeito está trabalhando em torno de alguma intervenção complicada do mundo real, mas não é assim que as coisas funcionam. A maioria dos programadores costuma escrever códigos confusos ou um pouco embaraçados, então, quando nos deparamos com isso, é uma inclinação natural para arrumar tudo. Eu juro que meu passado é um idiota real sempre que leio código antigo que escrevi.

Então eu não penso nos comentários como um pedido de desculpas por código ruim, mas talvez como uma explicação para por que você não fez a coisa óbvia. Ter // The standard approach doesn't work against the 64 bit version of the Frobosticate Library permitirá que futuros desenvolvedores, incluindo o seu futuro, prestem atenção a essa parte do código e testem contra essa biblioteca. Claro, você pode colocar os comentários em seus commits de controle de fonte também, mas as pessoas só olham para aqueles depois que algo deu errado. Eles vão ler os comentários do código enquanto eles mudam o código.

As pessoas que nos dizem que devemos sempre escrever código teoricamente perfeito nem sempre são pessoas com muita experiência de programação em ambientes do mundo real. Às vezes você precisa escrever um código que atinja um certo nível, às vezes você precisa interoperar com sistemas imperfeitos. Isso não significa que você não possa fazer isso de maneira elegante e bem escrita, mas soluções não óbvias precisam de explicação.

Quando escrevo código para projetos de hobbies que sei que ninguém mais lerá, ainda comento partes que acho confusas - por exemplo, qualquer geometria 3D envolve matemática com a qual não estou totalmente familiarizado - porque sei quando Eu volto em seis meses, eu vou ter esquecido completamente como fazer essas coisas. Isso não é um pedido de desculpas por código ruim, isso é um reconhecimento de uma limitação pessoal. Tudo o que eu faria, deixando-a descomentada, criaria mais trabalho para mim no futuro. Eu não quero que meu futuro eu tenha que reaprender algo desnecessariamente se eu puder evitá-lo agora. Qual valor possível teria?

    
por 01.09.2014 / 12:47
fonte
29

A necessidade de comentários é inversamente proporcional ao nível de abstração do código.

Por exemplo, a linguagem de montagem é, para fins mais práticos, ininteligível sem comentários. Aqui está um trecho de um pequeno programa que calcula e imprime os termos da série de Fibonacci :

main:   
; initializes the two numbers and the counter.  Note that this assumes
; that the counter and num1 and num2 areas are contiguous!
;
    mov ax,'00'                     ; initialize to all ASCII zeroes
    mov di,counter                  ; including the counter
    mov cx,digits+cntDigits/2       ; two bytes at a time
    cld                             ; initialize from low to high memory
    rep stosw                       ; write the data
    inc ax                          ; make sure ASCII zero is in al
    mov [num1 + digits - 1],al      ; last digit is one
    mov [num2 + digits - 1],al      ; 
    mov [counter + cntDigits - 1],al

    jmp .bottom         ; done with initialization, so begin

.top
    ; add num1 to num2
    mov di,num1+digits-1
    mov si,num2+digits-1
    mov cx,digits       ; 
    call    AddNumbers  ; num2 += num1
    mov bp,num2         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jz  .done           ;

    ; add num2 to num1
    mov di,num2+digits-1
    mov si,num1+digits-1
    mov cx,digits       ;
    call    AddNumbers  ; num1 += num2
.bottom
    mov bp,num1         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jnz .top            ;
.done
    call    CRLF        ; finish off with CRLF
    mov ax,4c00h        ; terminate
    int 21h             ;

Mesmo com comentários, pode ser bastante complicado para grok.

Exemplo moderno: Regexes são frequentemente construções de abstração muito baixas (letras minúsculas, número 0, 1, 2, novas linhas, etc). Eles provavelmente precisam de comentários na forma de amostras (Bob Martin, IIRC, reconhece isso). Aqui está uma regex que (eu acho) deve corresponder a URLs HTTP (S) e FTP:

^(((ht|f)tp(s?))\://)?(www.|[a-zA-Z].)[a-zA-Z0-9\-\.]+\.(com|edu|gov|m
+il|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(/($|[a-zA-Z0-9\.
+\,\;\?\'\\+&amp;%\$#\=~_\-]+))*$

À medida que as linguagens progridem na hierarquia de abstração, o programador pode usar abstrações evocativas (nome da variável, nomes de funções, nomes de classes, nomes de módulos, interfaces, retornos de chamada, etc) para fornecer documentação incorporada. Negligenciar tirar proveito disso, e usar comentários para escrever sobre isso é preguiçoso, um desserviço e desrespeito ao mantenedor.

Estou pensando em Receitas Numéricas em C traduzidas na maior parte das vezes em Receitas Numéricas em C ++ , as quais comecei como Receitas Numéricas FORTAN), com todas as variáveis a , aa , b , c , cc , etc. mantidas em cada versão. Os algoritmos podem estar corretos, mas não aproveitaram as abstrações fornecidas pelas linguagens. E eles me dispensam. Exemplo de um artigo do Dr. Dobbs - Fast Fourier Transform :

void four1(double* data, unsigned long nn)
{
    unsigned long n, mmax, m, j, istep, i;
    double wtemp, wr, wpr, wpi, wi, theta;
    double tempr, tempi;

    // reverse-binary reindexing
    n = nn<<1;
    j=1;
    for (i=1; i<n; i+=2) {
        if (j>i) {
            swap(data[j-1], data[i-1]);
            swap(data[j], data[i]);
        }
        m = nn;
        while (m>=2 && j>m) {
            j -= m;
            m >>= 1;
        }
        j += m;
    };

    // here begins the Danielson-Lanczos section
    mmax=2;
    while (n>mmax) {
        istep = mmax<<1;
        theta = -(2*M_PI/mmax);
        wtemp = sin(0.5*theta);
        wpr = -2.0*wtemp*wtemp;
        wpi = sin(theta);
        wr = 1.0;
        wi = 0.0;
        for (m=1; m < mmax; m += 2) {
            for (i=m; i <= n; i += istep) {
                j=i+mmax;
                tempr = wr*data[j-1] - wi*data[j];
                tempi = wr * data[j] + wi*data[j-1];

                data[j-1] = data[i-1] - tempr;
                data[j] = data[i] - tempi;
                data[i-1] += tempr;
                data[i] += tempi;
            }
            wtemp=wr;
            wr += wr*wpr - wi*wpi;
            wi += wi*wpr + wtemp*wpi;
        }
        mmax=istep;
    }
}

Como um caso especial sobre abstração, toda linguagem tem expressões idiomáticas / trechos de códigos canônicos para certas tarefas comuns (excluindo uma lista vinculada dinâmica em C), e independentemente de como elas se pareçam, elas não devem ser documentadas. Os programadores devem aprender esses idiomas, pois eles são extraoficialmente parte da linguagem.

Assim, o take away: Código não-idiomático construído a partir de blocos de construção de baixo nível que não podem ser evitados, precisa de comentários. E isso é necessário WAAAAY menos do que acontece.

    
por 02.09.2014 / 17:42
fonte
19

Não acredito que haja algo de errado com comentários no código. A idéia de que comentários são de alguma forma ruins na minha opinião é devido a alguns programadores levando as coisas longe demais. Há um monte de bandwagoning nesta indústria, especialmente para pontos de vista extremos. Em algum lugar ao longo do caminho, o código comentado tornou-se equivalente a um código incorreto e não sei por quê.

Os comentários têm problemas - você precisa mantê-los atualizados enquanto atualiza o código ao qual eles se referem, o que acontece muito raramente. Um wiki ou algo assim é um recurso mais apropriado para documentação completa sobre seu código. Seu código deve ser legível sem exigir comentários. Controle de versão ou notas de revisão devem ser onde você descreve as alterações de código feitas por você.

Nenhuma das opções anteriores invalida o uso de comentários, no entanto. Nós não vivemos em um mundo ideal, então quando qualquer um dos itens acima falhar por qualquer motivo, eu prefiro ter alguns comentários para retroceder.

    
por 01.09.2014 / 16:10
fonte
18

Eu acho que você está lendo um pouco demais para o que ele está dizendo. Existem duas partes distintas para a sua reclamação:

What's wrong with explaining (1) a complex algorithm or (2) a long and convoluted piece of code with a descriptive comment?

(1) é inevitável. Eu não acho que Martin discordaria de você. Se você está escrevendo algo como a raiz quadrada inversa rápida , você vai precisar de alguns comentários, mesmo que seja apenas "Malvado hacker em nível de bit flutuante". Exceto por algo simples como um DFS ou busca binária, é improvável que a pessoa que está lendo seu código tenha experiência com esse algoritmo, e então acho que deveria haver pelo menos uma menção nos comentários sobre o que é.

A maioria dos códigos não é (1), no entanto. Raramente você escreverá um software que não seja nada além de implementações mutex manuais, operações de álgebra linear obscuras com suporte a bibliotecas precário e novos algoritmos conhecidos apenas pelo grupo de pesquisa de sua empresa. A maioria dos códigos consiste em chamadas de biblioteca / framework / API, IO, clichê e testes de unidade.

Este é o tipo de código sobre o qual Martin está falando. E ele aborda sua pergunta com a citação de Kernighan e Plaugher no topo do capítulo:

Don’t comment bad code—rewrite it.

Se você tiver seções longas e complicadas em seu código, você falhou em manter seu código limpo . A melhor solução para esse problema não é escrever um comentário longo de parágrafo no topo do arquivo para ajudar futuros desenvolvedores a confundi-lo; A melhor solução é reescrevê-lo.

E é exatamente isso que Martin diz:

The proper use of comments is to compensate for our failure to express ourself in code...Comments are always failures. We must have them because we cannot always figure out how to express ourselves without them, but their use is not a cause for celebration.

Este é o seu (2). Martin concorda que um código longo e enrolado precisa de comentários - mas coloca a culpa por esse código nos ombros do programador que o escreveu, e não em uma idéia nebulosa de que "todos sabemos que isso não é suficiente". Ele argumenta que:

Clear and expressive code with few comments is far superior to cluttered and complex code with lots of comments. Rather than spend your time writing the comments that explain the mess you’ve made, spend it cleaning that mess.

    
por 01.09.2014 / 04:53
fonte
8

What's wrong with explaining a complex algorithm or a long and convoluted piece of code with a descriptive comment?

Nada como tal. Documentar seu trabalho é uma boa prática.

Dito isso, você tem uma falsa dicotomia aqui: escrever código limpo versus escrever código documentado - os dois não estão em oposição.

O que você deve focar é simplificar e abstrair o código complexo em um código mais simples, em vez de pensar que "o código complexo está bem, desde que seja comentado".

Idealmente, o seu código deve ser simples e documentado.

This way, instead of other developers (including yourself) having to read the entire algorithm line by line to figure out what it does, they can just read the friendly descriptive comment you wrote in plain English.

Verdadeiro. É por isso que todos os seus algoritmos públicos de API devem ser explicados na documentação.

So after writing a complex piece of code written in a partly human-readable programming language, why not add a descriptive and concise comment explaining the operation of the code in friendly and understandable English?

Idealmente, depois de escrever um código complexo, você deve (não uma lista exaustiva):

  • considere um rascunho (ou seja, planeje reescrevê-lo)
  • formalize os pontos de entrada do algoritmo / interfaces / roles / etc (analize e otimize a interface, formalize as abstrações, pré-condições do documento, pós-condições e efeitos colaterais e casos de erro do documento).
  • testes de gravação
  • limpeza e refatoração

Nenhuma dessas etapas é trivial (ou seja, cada uma pode levar algumas horas) e as recompensas por fazê-las não são imediatas. Como tal, estas etapas são (quase) sempre comprometidas (por desenvolvedores, esquinas, gerentes de corte, prazos, restrições de mercado / outras condições do mundo real, falta de experiência, etc.).

[...] some algorithms are complex. And therefore are hard to understand when reading them line by line.

Você nunca deve depender da leitura da implementação para descobrir o que uma API faz. Quando você faz isso, você está implementando o código do cliente baseado na implementação (ao invés da interface) e isso significa que o acoplamento do seu módulo já está para o inferno, você está potencialmente introduzindo dependências não documentadas a cada nova linha de código que você escreve, e já está adicionando dívida técnica.

Is it really that bad to explain a complex algorithm with a few lines of comments about it's general operation?

Não - isso é bom. Adicionar algumas linhas de comentários não é suficiente.

What's wrong with explaining complicated code with a comment?

O fato de você não ter código complicado, se isso puder ser evitado.

Para evitar códigos complicados, formalize suas interfaces, gaste ~ 8 vezes mais em design de API do que gasta na implementação (Stepanov sugeriu gastar pelo menos 10x na interface, em comparação com a implementação) e entrar no desenvolvimento de um projeto com o conhecimento de que você está criando um projeto, não apenas escrevendo algum algoritmo.

Um projeto envolve documentação de API, documentação funcional, medidas de código / qualidade, gerenciamento de projetos e assim por diante. Nenhum desses processos são passos rápidos e rápidos a serem feitos (todos eles levam tempo, exigem previsão e planejamento, e todos eles exigem que você volte a eles periodicamente e os revise / complete com detalhes).

    
por 01.09.2014 / 14:33
fonte
6

instead of other developers (including yourself) having to read the entire algorithm line by line to figure out what it does, they can just read the friendly descriptive comment you wrote in plain English.

Eu consideraria isso um leve abuso de "comentários". Se o programador quiser ler algo em vez de o algoritmo inteiro, então é para isso que serve a documentação da função. OK, então a documentação da função pode realmente aparecer nos comentários na fonte (talvez para extração por ferramentas doc), mas embora sintaticamente seja um comentário no que diz respeito ao seu compilador, você deve considerá-los separados com propósitos separados. Eu não acho que "os comentários devem ser escassos" significa necessariamente "documentação deve ser escassa" ou até mesmo "avisos de direitos autorais devem ser escassos"!

Os comentários na função são para alguém ler bem como o código. Então, se você tem algumas linhas em seu código que são difíceis de entender, e você não pode torná-las fáceis de entender, então um comentário é útil para o leitor usar como um espaço reservado para essas linhas. Isso pode ser muito útil enquanto o leitor está tentando obter a essência geral, mas há alguns problemas:

  • Os comentários não são necessariamente verdadeiros, enquanto o código faz o que faz. Então o leitor está aceitando a sua palavra e isso não é ideal.
  • O leitor ainda não entende o código em si, então até que ele volte a ele mais tarde, ele ainda não está qualificado para modificá-lo ou reutilizá-lo. Nesse caso, o que eles estão fazendo lendo?

Existem exceções, mas a maioria dos leitores precisará entender o próprio código. Comentários devem ser escritos para ajudar, e não para substituí-lo, e é por isso que você geralmente recomenda que os comentários digam "por que você está fazendo isso". Um leitor que conhece a motivação para as próximas linhas de código tem mais chances de ver o que eles fazem e como.

    
por 01.09.2014 / 10:41
fonte
5

Muitas vezes temos que fazer coisas complicadas. Certamente é certo documentá-los para futura compreensão. Às vezes, o lugar certo para esta documentação está no código, onde a documentação pode ser mantida atualizada com o código. Mas definitivamente vale a pena considerar uma documentação separada. Isso também pode ser mais fácil de apresentar a outras pessoas, incluindo diagramas, imagens coloridas e assim por diante. Então o comentário é apenas:

// This code implements the algorithm described in requirements document 239.

ou mesmo apenas

void doPRD239Algorithm() { ...

Certamente as pessoas estão felizes com as funções denominadas MatchStringKnuthMorrisPratt ou encryptAES ou partitionBSP . Nomes mais obscuros valem a pena explicar em um comentário. Você também pode adicionar dados bibliográficos e um link para um documento do qual você implementou um algoritmo.

Se um algoritmo é complexo e novo e não é óbvio, definitivamente vale a pena um documento, mesmo que apenas para a circulação interna da empresa. Verifique o documento no controle de origem se estiver preocupado com a possibilidade de se perder.

Existe outra categoria de código que não é tanto algorítmica quanto burocrática. Você precisa configurar parâmetros para outro sistema ou interoperar com os erros de outra pessoa:

/* Configure the beam controller and turn on the laser.
The sequence is timing-critical and this code must run with interrupts disabled.
Note that the constant 0xef45ab87 differs from the vendor documentation; the vendor
is wrong in this case.
Some of these operations write the same value multiple times. Do not attempt
to optimise this code by removing seemingly redundant operations.
*/
    
por 01.09.2014 / 16:50
fonte
5

Eu esqueço onde li, mas há uma linha clara e nítida entre o que deve aparecer no seu código e o que deve aparecer como um comentário.

Eu acredito que você deve comentar sua intenção, não seu algoritmo . Ou seja comenta o que você pretendia fazer, não o que você faz .

Por exemplo:

// The getter.
public <V> V get(final K key, Class<V> type) {
  // Has it run yet?
  Future<Object> f = multitons.get(key);
  if (f == null) {
    // No! Make the task that runs it.
    FutureTask<Object> ft = new FutureTask<Object>(
            new Callable() {

              public Object call() throws Exception {
                // Only do the create when called to do so.
                return key.create();
              }

            });
    // Only put if not there.
    f = multitons.putIfAbsent(key, ft);
    if (f == null) {
      // We replaced null so we successfully put. We were first!
      f = ft;
      // Initiate the task.
      ft.run();
    }
  }
  try {
    /**
     * If code gets here and hangs due to f.status = 0 (FutureTask.NEW)
     * then you are trying to get from your Multiton in your creator.
     *
     * Cannot check for that without unnecessarily complex code.
     *
     * Perhaps could use get with timeout.
     */
    // Cast here to force the right type.
    return (V) f.get();
  } catch (Exception ex) {
    // Hide exceptions without discarding them.
    throw Throwables.asRuntimeException(ex);
  }
}

Aqui não há nenhuma tentativa de declarar o que cada etapa executa, tudo o que ela afirma é o que deve fazer.

PS: Eu encontrei a fonte que eu estava me referindo - Coding Horror: Código diz a você como, comentários dizem por que

    
por 01.09.2014 / 13:06
fonte
4

But we all know that's not enough.

Realmente? Desde quando?

Código bem projetado com bons nomes é mais que suficiente na grande maioria dos casos. Os argumentos contra o uso de comentários são bem conhecidos e documentados (como você se refere).

Mas estas são diretrizes (como qualquer outra coisa). No caso raro (na minha experiência, cerca de uma vez a cada dois anos) onde as coisas seriam piores quando refatoradas em funções legíveis menores (devido a necessidades de desempenho ou coesão), então vá em frente - faça um longo comentário explicando o que a coisa é realmente fazendo (e porque você está violando as melhores práticas).

    
por 01.09.2014 / 02:57
fonte
2

O principal objetivo do código é comandar um computador para fazer algo, então um bom comentário nunca é um substituto para um bom código porque os comentários não podem ser executados.

Dito isto, comentários na fonte são uma forma de documentação para outros programadores (incluindo você). Se os comentários forem sobre questões mais abstratas do que o código está fazendo a cada passo, você está se saindo melhor do que a média. Esse nível de abstração varia com a ferramenta que você está usando. Os comentários que acompanham as rotinas da linguagem assembly geralmente têm um nível mais baixo de "abstração" do que, por exemplo, este APL A←0⋄A⊣{2⊤⍵:1+3×⍵⋄⍵÷2}⍣{⍺=A+←1}⎕ . Eu acho que provavelmente mereceria um comentário sobre o problema que pretende solucionar, hmmm?

    
por 01.09.2014 / 04:12
fonte
2

Se o código é trivial, não é necessário um comentário explicativo. Se o código não for trivial, o comentário explicativo provavelmente também não será trivial.

Agora, o problema com a linguagem natural não-trivial é que muitos de nós não são muito bons em ler ou escrever. Tenho certeza de que suas habilidades de comunicação por escrito são excelentes, mas mesmo assim alguém com uma compreensão menor da linguagem escrita pode interpretar mal suas palavras.

Se você se esforçar muito para escrever uma linguagem natural que não possa ser mal interpretada, você acaba com algo como um documento legal (e como todos nós sabemos, eles são mais verbosos e difíceis de entender do que o código).

O código deve ser a descrição mais concisa da sua lógica, e não deve haver muito debate sobre o significado do seu código porque o seu compilador e plataforma têm a palavra final.

Pessoalmente, eu não diria que você nunca deve escrever um comentário. Só você deve considerar por que seu código precisa de um comentário e como você pode consertar isso. Este parece ser um tema comum nas respostas aqui.

    
por 01.09.2014 / 15:00
fonte
0

Um ponto ainda não mencionado é que, às vezes, comentar exatamente o que uma parte do código faz pode ser útil em casos em que uma linguagem usa uma sintaxe específica para várias finalidades. Por exemplo, supondo que todas as variáveis sejam do tipo float , considere:

f1 = (float)(f2+f3); // Force result to be rounded to single precision
f4 = f1-f2;

O efeito de converter explicitamente um float para float é forçar o resultado a ser arredondado para precisão única; o comentário poderia, portanto, ser visto como simplesmente dizendo o que o código faz. Por outro lado, compare esse código com:

thing.someFloatProperty = (float)(f2*0.1); // Divide by ten

Aqui, o objetivo do elenco é evitar que o compilador grite da maneira mais eficiente de calcular com precisão (f2 / 10) [é mais preciso que multiplicar por 0,1f e na maioria das máquinas é mais rápido que dividir por 10,0 f].

Sem o comentário, alguém que estava revisando o código anterior pode pensar que o elenco foi adicionado por acreditar erroneamente que seria necessário impedir que o compilador grasnasse e que não era necessário. De fato, o elenco serve ao propósito de fazer exatamente o que a linguagem diz que faz: forçar o resultado da computação a ser arredondado para precisão única mesmo em máquinas onde o arredondamento seria mais caro do que manter o resultado em maior precisão. Dado que uma conversão para float pode ter vários significados e propósitos diferentes, ter um comentário especificando qual significado é intencional em um cenário específico pode ajudar a deixar claro que o significado real alinha-se à intenção.

    
por 01.09.2014 / 17:35
fonte
-1

Comentários que explicam o que o código faz são uma forma de duplicação. Se você alterar o código e depois esquecer de atualizar os comentários, isso pode causar confusão. Eu não estou dizendo não os use, apenas use-os judiciosamente. Eu assino a máxima do Uncle Bob: "Apenas comente o que o código não pode dizer".

    
por 07.02.2015 / 13:36
fonte