17 de julho de 2010

// Não comente seu código

Você usa desodorante nas axilas? Se usa, provavelmente o faz por causa do mau cheiro produzido pelas suas glândulas sudoríparas dessa região.

É por um motivo semelhante que muitos programadores escrevem comentários. Seu código é difícil de compreender, por isso precisa ser comentado. Mas se o código ruim fosse refatorado até se tornar um bom código, a maioria dos comentários seriam desnecessários.

1 - Comentários como desodorante

Com a ajuda do Martin Fowler no seu livro sobre refatoração, me dei conta de que muitos dos comentários que eu escrevia no passado eram usados para minimizar os efeitos de um código ruim (do ponto de vista da clareza, não da eficiência). O código ruim, segundo Fowler, cheira mal e os comentários, neste caso, agem como desodorante. A seguir, alguns desses maus usos de comentários.

1.1 - Para compensar a má nomeação de identificadores

Se você sentir a necessidade de comentar pra que serve uma váriável, constante, função, parâmetro de função, atributo, classe ou método*, provavelmente o nome que você deu ao identificador não é um bom nome.

Sem ser dogmático, sugiro o seguinte:

'Quando você sentir a necessidade de escrever um comentário para explicar o que faz ou pra que serve determinado identificador, transforme o comentário que você escreveria no nome do identificador.' (uma adaptação de algumas frases do Fowler)

Transformar um comentário curto em um nome de variável é fácil (a menos que você use uma variável para várias coisas diferentes). Mas, transformar um comentário de várias linhas em um nome de função dará mais trabalho, porém, neste caso, os comentários longos são consequência de um outro problema: funções longas.

1.2 - Para compensar a escrita de funções longas

Quem escreve uma função com muitas linhas, normalmente sente a necessidade de adicionar um comentário junto à declaração da função para explicar as coisas que ela faz. No corpo de funções desse tipo, também é comum encontrar comentários para explicar certos agrupamentos de código. Em ambos os casos, os comentários são um indício de que o código não está suficientemente claro.

Ao invés de se eximir da responsabilidade pelo mau código atrás de comentários, refatore o código desmembrando a função longa em várias funções menores. Se há comentários ao longo do corpo da função, esses comentários dão uma dica do que pode ser extraído e do nome que você pode dar a cada função extraída.

Laços com muitas linhas de código dentro de uma função são terríveis para compreender, especialmente laços aninhados. Se você reduzir o número de linhas dentro de um laço de forma que possa observar sem usar scroll onde começa e onde termina o laço, seu código será mais fácil de compreender.

1.3 - Para explicar o uso de strings e números literais

Strings e números literais são valores escritos diretamente no código. Por exemplo, em certo programa, pode ser convencionado que os tipos de inscrição CPF e CNPJ serão representados pelos inteiros 1 e 2, respectivamente. Se o programador decidir usar os literais 1 e 2 em todo código que lide com os tipos de inscrição, ele provavelmente compensará isso com o uso de comentários. Exemplo (em Java):

/* Exemplo A */
String getInscricaoFormatada1(int tipoInscricao, String inscricao) {

  if (tipoInscricao==1) /* 1=CPF */
    return formatarTexto("999.999.999-99", inscricao);
  else if (tipoInscricao==2) /* 2=CNPJ */
    return formatarTexto("99.999.999/9999-99", inscricao);
  else
    return inscricao;
}

Apesar de o código acima permitir uma fácil compreensão, o próximo código - que não usa comentários - tende a ser mais adequado.

/* Exemplo B */
static final int TIPO_INSCRICAO_CPF = 1;
static final int TIPO_INSCRICAO_CNPJ = 2;

String getInscricaoFormatada2(int tipoInscricao, String inscricao) {

  if (tipoInscricao == TIPO_INSCRICAO_CPF)
    return formatarTexto("999.999.999-99", inscricao);
  else if (tipoInscricao == TIPO_INSCRICAO_CNPJ)
    return formatarTexto("99.999.999/9999-99", inscricao);
  else
    return inscricao;
}

A alternativa "B" é preferível porque, além de dispensar o uso de comentários, evita erros. Se você digitar incorretamente o nome de uma constante ao fazer uso dela, o compilador perceberá, enquanto ele não poderá ajudar se você fizer uso de um literal incorreto.

3 - Quando usar comentários?

Tudo bem se você achar que estou sendo contraditório neste tópico por causa do título que escolhi para o artigo. A verdade é que eu gosto dos comentários, desde que não sejam usados como desodorante. Aqui vão alguns dos usos que considero adequados.

3.1 - Para organizar o pensamento sobre o código

Quando não uso um quadro ou papel para rascunhar o que vou codificar, uso comentários para criar uma lista de passos que preciso seguir para atingir o objetivo do código. Esses passos não precisam ser precisos, apenas precisam ser "persistidos" em algum lugar para que eu não esqueça deles. À medida que os passos são concluídos, removo os comentários, pois nesse ponto se tornam irrelevantes.

3.2 - Para marcar código duvidoso, passível de melhora ou incompleto

Há casos em que algumas suposições precisam ser temporariamente assumidas como verdadeiras para que a codificação flua sem empecilhos. Nestes casos, é útil marcar o código duvidoso com um comentário precedido por um "TODO" ("fazer", em inglês). O mesmo se dá com códigos passíveis de melhora ou incompletos. Alguns exemplos:

  /* TODO: confirmar se o DV da conta é calculado com módulo 10 */
  /* TODO: refatorar este código para remover as duplicações /*
  /* TODO: validar campos obrigatórios antes de gravar /*

PS: IDE's de desenvolvimento modernas permitem a fácil localização dos comentários marcados com "TODO".

3.3 - Para explicar porque você fez algo

Há certas ocasiões em que você precisa explicar porque fez algo no código - especialmente quando isso torna o código mais complexo. Quando não é óbvio o porquê de uma decisão e você não esclarece isso com comentários, há o risco de que algum programador, ao assumir o seu trabalho, torne o código mais simples - o que pode levar a falhas que ele não tem condições de prever ou a um mau desempenho.

Um bom exemplo é um comentário escrito por nada menos que Linus Torvalds num arquivo fonte do Git (em C) para justificar a criação de um alocador de memória especializado ao invés de utilizar a função malloc() padrão:

  /*
   * alloc.c  - specialized allocator for internal objects
   *
   * Copyright (C) 2006 Linus Torvalds
   *
   * The standard malloc/free wastes too much space for objects, partly
   * because it maintains all the allocation infrastructure (which isn't
   * needed, since we never free an object descriptor anyway), but even
   * more because it ends up with maximal alignment because it doesn't
   * know what the object alignment for the new allocation is.
   */

Conclusão

Para encerrar, duas ótimas citações:

"Qualquer tolo consegue escrever código que um computador entenda. Bons programadores escrevem código que humanos possam entender." (Martin Fowler)
"Sempre codifique como se o programador que vai dar manutenção no seu código fosse um serial killer maníaco que sabe onde você mora." (autor desconhecido)

Gostou do que leu? Deixe seu /*comentário*/.

* ^ A rigor, variável e atributo são coisas diferentes, assim como função e método. Mas, para fins de simplificação, quando eu disser "variável", estarei me referindo também a "atributo" e quando disser "função" estarei me referindo também a método.

Crédito da foto: George Marks

Referências:

25 comentários:

Magno Machado Paulo disse...

Concordo totalmente. Melhor do que código todo comentário, é código que simplesmente não precisa de comentários.

Eu tive um professor na faculdade que dizia que tirava ponto dos alunos que não comentavam os códigos nas provas e trabalhos. Na época eu achei a atitude dele o máximo, mas hoje vejo que o professor estava tremendamente equivocado

Dirlei Dionísio disse...

Essa sua história do professor me lembrou o que o diretor de uma empresa onde trabalhei dizia: "Quem sabe faz, quem não sabe ensina".

Obrigado pelo comentário! Um abraço, Magno.

Unknown disse...

Muito bem lembrado...hoje em dia as linguagens de alto nível já tornam a comunicação entre os programadores e o computador muito simples, não há a necessidade de comentar que //2+2 = 4. O comentário é bom pra quem não conhece muito uma linguagem e está estudando ainda...

Parabéns Dirlei...blog muito interessante! Abraço

Dirlei Dionísio disse...

Você tocou num ponto que eu não tinha pensado: que comentários são úteis durante a fase de aprendizado. É engraçado que hoje mesmo encontrei um monte de comentários um tanto óbvios num código que escrevi uns anos atrás onde trabalho (foram escritos por um estagiário que estava estudando o software pra assumir a manutenção).

Volte mais vezes Gustavo! Um abraço!

Alexandre disse...

Na minha visão, os comentários visam o objetivo de explicar o "porque?" e não o "para que?".

Não escrevo um comentário dizendo o que um método faz.Isso é por conta da assinatura do método.

Por exemplo:
Ecrevo um comentário, em alguns casos, explicando o porque foi criado um método "igual" a um outro já existente. Isso pelo fato do comportamento interno do método em alguns pontos serem diferentes.

Parabéns pelo blog e um Grande abraço!

Raquel Machado disse...

Parabéns pelo blog, adorei o jeito como você escreve! Também acho que comentários são bons pra quem não conhece muito uma linguagem,assim coloca umas "colinhas" sobre determinada linha de código e dessa forma acaba fixando.
Adorei isso rs "Sempre codifique como se o programador que vai dar manutenção no seu código fosse um serial killer maníaco que sabe onde você mora." Beijos!

Raquel Machado disse...

Achei interessante o que você disse sobre as IDE's de desenvolvimento modernas permitirem a fácil localização dos comentários marcados com "TODO". Pode me dar alguns exemplos?

Dirlei Dionísio disse...

Muito obrigado Raquel!

Sobre a exibição dos comentários com "TODO" nas IDE's...

Eclipse -> Window/Show View/Tasks
Netbeans -> Window/Tasks
Delphi -> View/To-Do-list

Um abraço!

Samuel Vinícius disse...

Não conhecia o blog, mas achei o post muito bom.

Parabens!

Com relação ao TODO isso realmente é ótimo. No meu caso, que uso Ruby on Rails, ele já é nativo da linguagem = )

Dirlei Dionísio disse...

Legal ter alguém da comunidade Rails no meu blog! Obrigado pelo comentário, Samuel! [ ]'s

Daniel Bruno disse...

Eu costumava usar milhares de comentários. Até o dia em que apaguei TODOS os comentários em uma classe (header e source, em c++) e me forcei a explicar o código mentalmente.

Simplesmente não consegui explicar um código que EU havia escrito.

Depois disso, passei a tomar muito cuidado e a tentar deixar o código auto-explicativo. Hoje comento em algumas partes do código por haver muita gente que torce o nariz se não ver alguns "//" espalhados. Mas na maior parte das vezes considero quase um pleonasmo, rs.

Dirlei Dionísio disse...

Se seus comentários quase sempre são um pleonasmo, isso é ótimo! Sinal de que seu código está claro e autoexplicativo. Ocasionalmente você pode experimentar acrescentar aos seus comentários redundantes algo como:

"Me desculpe por este comentário redundante, é que há programadores que não sabem que código bom é código que não precisa de comentários."

Hehehe...

Um abraço!

Alonso Jr. disse...

Muito bom artigo. Também sou totalmente contra comentários. Acho que(quando o código é bom, lógico), comentários só servem pra ensinar a quem não sabe programar. Por mais que o código seja limpo, sempre vai ter alguém que não vai entendê-lo. Mas nesse caso é provável que nem os comentários ajudem...

Parabéns pelo blog!

Dirlei Dionísio disse...

Obrigado, Alonso!

Leonardo Moulin Franco disse...

Olá. Muito bom o texto!!!

Dê uma olhada neste aqui também:
http://blog.qualidata.com.br/?p=669

Abraços!

Dirlei Dionísio disse...

Bacana, Leonardo! Gostei do artigo, até deixei um comentário lá. Li ainda alguns outros artigos e informações sobre a empresa. Me pareceu um ótimo lugar para trabalhar.

Valeu pela visita e pelo comentário!

[]'s

Darthjee disse...

na verdade, existe um ponto não abordado aqui
nem todas as linguages prevem um código limpo (imagine programar em assembler sem comentar)
ou as vezes, temos um algorítimo maluco demais, mas eficiente, por isso ele vai precisar de comentários (as vezes programamos para máquinas de baixo desempenho)
portanto concordo com os pontos apresentados, mas não com a conclusão final

Rinaldi disse...

um javadoc geralmente basta, fala pra que serve, etc.

Dirlei Dionísio disse...

Olá Darthjee, obrigado pela visita e pelo comentário. A intenção do artigo foi desestimular o uso dos comentários que tentam compensar a má qualidade do código. Código ruim deve ser refatorado, não explicado com comentários. É claro que sempre haverá comentários dignos de serem escritos e eu citei alguns desses exemplos. Um código Assembly certamente tem mais motivos para ser comentado que códigos em linguagens de alto nível, mas o princípio continua o mesmo: não usar comentários como desodorante.

Grande abraço!

Darthjee disse...

Neste ponto, sem dúvida que tenho que concordar, afinal, comentário deve ser útil e não redundante ... lembro quando perdi ponto em trabalho por falta de comentário e decidi comentar tudinho só pra encher o saco

Anônimo disse...

Discordo e com prova, sei fazer mas adoro ensinar, então faço durante o dia e ensino anoite;

Anônimo disse...

Não concordo que um código bom não deve ter comentario. O comentário serve para descrever o que será feito.
um exemplo é se você faz uns calculos com valores de ICMS, vc precisa descrever de onde veio esses valores.
Cada caso é um caso. não podemos generalizar.

Dirlei Dionísio disse...

Concordo plenamente, Anônimo. Foi por isso que não generalizei.

Dirlei Dionísio disse...

Tem certeza que sabe, Anônimo? Brincadeira, estou apenas sendo irônico, como fui no comentário anterior. Bons programadores que também são bons professores são raros, mas não duvido que existam. Parabéns por ser um deles. Abraço!

Anônimo disse...

"Sempre codifique como se o programador que vai dar manutenção no seu código fosse um serial killer maníaco que sabe onde você mora." (autor desconhecido)

kkkkkkkkkkkkkkkkkkkkkkkkkkkkkk

muito boaa kkkkkkkkkkkkkkkkkkk