Estilo e recomendações do código de comentários

26

Quero ouvir de você algum conselho e experiência em escrever comentários em seu código. Como você os escreve da maneira mais fácil e informativa? Que hábitos você tem ao comentar partes do código? Talvez algumas recomendações exóticas?

Espero que esta pergunta colete os conselhos e recomendações mais interessantes para comentar, algo útil que todos possam aprender.

OK, eu vou começar.

  1. Normalmente, não uso /* */comentários, mesmo quando preciso comentar muitas linhas.

    Vantagens : o código visualmente parece melhor do que quando você mistura essa sintaxe com comentários de uma linha. A maioria dos IDEs tem a capacidade de comentar o texto selecionado e geralmente o faz com sintaxe de uma linha.

    Desvantagens : Difícil editar esse código sem o IDE.

  2. Coloque "ponto" no final de qualquer comentário finalizado.

    Por exemplo:

    //Recognize wallpaper style. Here I wanted to add additional details
    int style = int.Parse(styleValue);
    //Apply style to image.
    Apply(style);
    

    Vantagens : Coloque "ponto" apenas nos comentários que você terminou. Às vezes, você pode escrever informações temporais; portanto, a falta de "ponto" indica que você deseja retornar e adicionar algum texto adicional a esse comentário.

  3. Alinhar texto nas enumerações, comentar parâmetros etc.

    Por exemplo:

    public enum WallpaperStyle
    {
        Fill = 100,     //WallpaperStyle = "10"; TileWallpaper = "0".
        SizeToFit = 60, //WallpaperStyle = "6";  TileWallpaper = "0".
        Stretch = 20,   //WallpaperStyle = "2";  TileWallpaper = "0".
        Tile = 1,       //WallpaperStyle = "0";  TileWallpaper = "1".
        Center = 0      //WallpaperStyle = "0";  TileWallpaper = "0".
    };
    

    Vantagens : Apenas parece melhor e visualmente mais fácil de encontrar o que você precisa.

    Desvantagens : gastar tempo para alinhar e mais difícil para editar.

  4. Escreva um texto no comentário que você não pode obter analisando o código.

    Por exemplo, comentário estúpido:

    //Apply style.
    Apply(style);
    

    Vantagens : você terá um código claro e pequeno, com apenas informações úteis nos comentários.

Kyrylo M
fonte
2
Alinhar comentários no vim: use Align.vim e faça :3,7 Align //para alinhar comentários nas linhas 3-7.
Benoit
3
"Difícil de editar sem IDE" - bem, você faz isso com frequência?
3
Eu acho que uma preferência de idioma / ambiente deve ser observada na pergunta. Alguns têm diretrizes existentes (o .NET possui comentários xml bastante padrão: msdn.microsoft.com/en-us/library/b2s063f7.aspx ).
Steven Evers
+1 SnOrfus. Para comentários em Java, para ser usado em Javadocs, a documentação do desenvolvedor precisa ser colocada em comentários de asterisco duplo, que devem ser colocados antes do seu código. Os comentários do Javadoc são transformados em html; portanto, você pode usar uma lista de marcadores, uma tabela, uma imagem ou um URL em seu comentário e, em todos os casos, um ponto final pode ser perturbador.
usuário desconhecido

Respostas:

16

Algumas das afirmações abaixo são bastante pessoais, embora com alguma justificativa, e devem ser assim.

Tipos de comentário

Para a versão resumida ... Eu uso comentários para:

  • comentários finais explicando campos nas estruturas de dados (além desses, eu realmente não uso comentários de linha única)
  • comentários de várias linhas excepcionais ou orientados para o objetivo acima dos blocos
  • documentação pública de usuário e / ou desenvolvedor gerada a partir da fonte

Leia abaixo os detalhes e (possivelmente obscuros) motivos.

Comentários finais

Dependendo do idioma, use comentários de uma linha ou comentários de várias linhas. Por que isso depende? É apenas uma questão de padronização. Quando escrevo código C, sou a favor do código ANSI C89 à moda antiga, por isso prefiro sempre /* comments */.

Portanto, eu teria isso em C na maioria das vezes, e às vezes (depende do estilo da base de código) para idiomas com uma sintaxe semelhante a C:

typedef struct STRUCT_NAME {
  int fieldA;                /* aligned trailing comment */
  int fieldBWithLongerName;  /* aligned trailing comment */
} TYPE_NAME;

O Emacs é legal e faz isso comigo M-;.

Se o idioma suportar comentários de linha única e não for baseado em C, estarei mais inclinado a usar os comentários de linha única. Caso contrário, receio que agora tenha adquirido o hábito. O que não é necessariamente ruim, pois me força a ser conciso.

Comentários de várias linhas

Não concordo com o seu preceito usando comentários de linha única, pois isso é mais visualmente atraente. Eu uso isso:

/*
 * this is a multi-line comment, which needs to be used
 * for explanations, and preferably be OUTSIDE the a
 * function's or class' and provide information to developers
 * that would not belong to a generated API documentation.
 */

Ou isso (mas não o faço com frequência, exceto em uma base de código pessoal ou principalmente em avisos de direitos autorais - isso é histórico para mim e vem da minha formação educacional. Infelizmente, a maioria dos IDEs estraga tudo ao usar o formato automático) :

/*
** this is another multi-line comment, which needs to be used
** for explanations, and preferably be OUTSIDE the a
** function's or class' and provide information to developers
** that would not belong to a generated API documentation.
*/

Se for realmente necessário, gostaria de comentar em linha usando o que mencionei anteriormente para comentários finais, se fizer sentido usá-lo em uma posição final. Em um caso de retorno muito especial, por exemplo, ou para documentar switchas caseinstruções de a (raro, não uso a opção frequentemente), ou quando documento ramificações em um if ... elsefluxo de controle. Se esse não é um desses, geralmente um bloco de comentários fora do escopo que descreve as etapas da função / método / bloco faz mais sentido para mim.

Eu as uso excepcionalmente, exceto se estiver codificando em um idioma sem suporte para comentários na documentação (veja abaixo); Nesse caso, eles se tornam mais prevalentes. Mas, no caso geral, é realmente apenas para documentar coisas que são destinadas a outros desenvolvedores e são comentários internos que realmente precisam se destacar. Por exemplo, para documentar um bloco vazio obrigatório como um bloco "forçado" catch:

try {
  /* you'd have real code here, not this comment */
} catch (AwaitedException e) {
  /*
   * Nothing to do here. We default to a previously set value.
   */
}

O que já é feio para mim, mas eu toleraria em algumas circunstâncias.

Comentários da documentação

Javadoc e cols.

Normalmente, eu os usava em métodos e classes para documentar versões que introduzem um recurso (ou alterá-lo), especialmente se for para uma API pública, e para fornecer alguns exemplos (com casos claros de entrada e saída e casos especiais). Embora, em alguns casos, um caso de unidade possa ser melhor para documentá-los, os testes de unidade não são necessariamente legíveis por humanos (não importa qual DSL você usa).

Eles me incomodam um pouco para documentar campos / propriedades, pois eu prefiro comentários finais para isso e nem toda estrutura de geração de documentação suporta comentários de documentação finais. O Doxygen faz, por exemplo, mas o JavaDoc não, o que significa que você precisa de um comentário importante para todos os seus campos. No entanto, posso sobreviver a isso, como as linhas Java são relativamente longas na maioria das vezes, então um comentário à parte me assustaria igualmente ao estender a linha além do meu limite de tolerância. Se Javadoc algum dia considerasse melhorar isso, eu ficaria muito mais feliz.

Código comentado

Eu uso a linha única por uma única razão, em idiomas do tipo C (exceto se estiver compilando para C estrito, onde eu realmente não os uso): para comentar coisas durante a codificação. A maioria dos IDEs terá alternado para comentários de linha única (alinhados no travessão ou na coluna 0), e isso se encaixa nesse caso de uso para mim. Usar a alternância para comentários com várias linhas (ou selecionar no meio das linhas, para alguns IDEs) tornará mais difícil alternar entre comentário / comentário com facilidade.

Mas, como sou contra o código comentado no SCM, isso geralmente é muito curto, porque vou excluir os pedaços comentados antes de confirmar. (Leia minha resposta a esta pergunta em "comentários editados por linha e SCMs" )

Estilos de comentário

Eu costumo escrever:

  • complete frases com gramática correta (incluindo pontuação) para comentários na documentação, pois eles devem ser lidos posteriormente em um documento da API ou mesmo como parte de um manual gerado.
  • bem formatado, mas mais relaxado na pontuação / limites para blocos de comentários de várias linhas
  • blocos finais sem pontuação (por causa do espaço e geralmente porque o comentário é breve, que se parece mais com uma declaração entre parênteses)

Uma nota sobre programação alfabetizada

Talvez você queira se interessar por programação alfabética , conforme apresentado neste artigo por Donald Knuth .

O paradigma da programação alfabetizada representa [...] um afastamento da escrita de programas da maneira e ordem impostas pelo computador e, em vez disso, permite que os programadores desenvolvam programas na ordem exigida pela lógica e pelo fluxo de seus pensamentos. 2 Programas alfabetizados são escritos como uma exposição ininterrupta da lógica em uma linguagem humana comum, como o texto de um ensaio [...].

As ferramentas de programação alfabetizada são usadas para obter duas representações de um arquivo de origem alfabetizado: uma adequada para compilação ou execução adicional por um computador, o código "emaranhado" e outra para exibição como documentação formatada, que se diz "tecida" do fonte alfabetizada.

Como observação e exemplo: A estrutura JavaScript underscore.js , apesar da não conformidade com meu estilo de comentário, é um bom exemplo de uma base de código bem documentada e de uma fonte anotada bem formada - embora talvez não seja a melhor para usar como uma referência de API).


Estas são convenções pessoais . Sim, eu posso ser estranho (e você também). Tudo bem, desde que você siga e cumpra as convenções de código de sua equipe ao trabalhar com colegas ou não ataque radicalmente suas preferências e coabite bem. Faz parte do seu estilo, e você deve encontrar a linha tênue entre o desenvolvimento de um estilo de codificação que o define como codificador (ou como seguidor de uma escola de pensamento ou organização com a qual você tem uma conexão) e respeitar a convenção de um grupo por consistência .

haylem
fonte
+1 para distinguir o código comentado dos comentários da documentação. Eu odeio caçar aqueles: P
deltreme
@ deltreme: obrigado. Sinto sua dor, estou caçando um monte deles no meu produto atual também. Os SCMs existem por um motivo ... Estou muito tentado a usar uma pesquisa de texto completo com uma expressão regular no Eclipse ou no Emacs e apenas erradicá-los um por um ... Tenho mais coisas produtivas para fazer, infelizmente :(
haylem 23/08
Consulte também esta resposta sobre o uso de tags de ação ou tarefa nos comentários .
21412 haylem
14

Quando fui para a universidade, sempre fui ensinado a comentar todas as linhas de código e todos os cabeçalhos de métodos. Foi tocado / doutrinado a tal ponto que você o fez sem questionar. Tendo participado de várias equipes de desenvolvimento Agile em diferentes empresas, posso dizer que posso escrever um comentário uma vez na lua azul.

A razão para isso é dupla: primeiro, não devemos mais escrever métodos monolíticos longos que fazem 101 coisas diferentes; os nomes de classe, método e variável devem ser auto-documentados. Tome o seguinte método de login como exemplo.

public void Login(string username, string password)
{
    // Get the user entity
    var user = userRepository.GetUser(username);


    // Check that the user exists
    if (user == null)
    {
        throw new UserNotFoundException();
    }

    // Check that the users password matched
    if (user.HashedPassword != GetPasswordHash(password))
    {
        throw new InvalidUsernamePasswordException();
    }

    //Check that the users account has not expired
    if (user.Expired)
    {
        throw new UserExpiredException();
    }

    //Mark user as logged in
    ...
}

Isso pode ser reescrito para algo que é muito mais legível e talvez reutilizável:

public void Login(string username, string password)
{
    var user = GetUserForUsername(username);

    CheckUsersPasswordMatched(user, password);

    CheckUserAccountNotExpired(user);

    MarkUserAsLoggedIn(user);
}

private void User GetUserForUsername(string username)
{
    var user = userRepository.GetUser(username);

    if (user == null)
    {
        throw new UserNotFoundException();
    }
    return user;
}

private void CheckUsersPasswordMatched(User user, string password)
{
    if (user.HashedPassword != GetPasswordHash(password))
    {
        throw new InvalidUsernamePasswordException();
    }
}

private void CheckUserAccountNotExpired(User user)
{
    if (user.Expired)
    {
        throw new UserExpiredException();
    }
}

Você pode ver claramente no método de login o que está acontecendo. Você pode ver isso como um trabalho extra, mas seus métodos são pequenos e têm apenas um trabalho. Além disso, os nomes dos métodos são descritivos, portanto não há necessidade de escrever nenhum comentário no cabeçalho do método. Se você acabar com muitos métodos, isso indica que os métodos relacionados devem ser fatorados novamente em outro objeto, como um UserAuthenticationService, lembre-se de que um objeto deve ter apenas um trabalho.

Em segundo lugar, cada pedaço de código que você escreve, incluindo comentários, precisa ser mantido, quanto mais comentários você tiver, mais há para manter. Se você renomear uma classe ou uma variável, receberá um erro de compilação, mas se alterar a maneira como uma seção de código funciona ou removê-la e não atualizar nenhum comentário relacionado, não haverá erro de compilação e os comentários permanecerão causando confusão. .

Se você estiver escrevendo uma API, acredito que quaisquer interfaces, classes e enumerações voltadas para o público devem ter comentários de cabeçalho bem escritos para documentação.

Bronumski
fonte
2
Concordo completamente com isto. Métodos curtos bem nomeados são auto-documentados. Na maioria das vezes, escrevo muito poucos (se houver) comentários no código e escreverei uma página wiki bastante grande com exemplos de código (geralmente feitos quando você está escrevendo uma biblioteca que outros desenvolvedores usarão).
25711 Kevin
2
Isto é exatamente o que eu vim aqui para dizer. Na verdade, passo tanto tempo pensando em nomes de variáveis, nomes de métodos, nomes de classes, etc. quanto em escrever código. O resultado, acredito, é um código muito suportável. Claro, às vezes tenho métodos chamados algo como checkIfUnitInvestigationExistsAndCreateNewRootCauseListIfItDoes () ... sim, os nomes dos métodos SOMETIMES ficam longos, mas acho que a capacidade de suporte do código é a faceta mais importante do desenvolvimento (além da velocidade de lançamento).
Jeremy.mooer
5

Concentre-se menos no formato e mais no conteúdo. Por exemplo, os comentários no seu exemplo não me dizem nada de novo. Eles são piores do que inúteis, pois prejudicam a leitura do código, e comentários como esses são, na melhor das hipóteses, uma referência vaga ao que o programador original pensou que estava fazendo no momento em que o escreveu. Eu posso ver no exemplo de código que você está aplicando um estilo "apply (Style)", eu posso ler a fonte. Não consigo ler sua mente - por que você está fazendo isso é o que o comentário deve me dizer. por exemplo, em vez de

//Apply style.

Apply(style);

deveria estar

// Unlike the others, this image needs to be drawn in the user-requested style apply(style);

A maioria de nós trabalha em equipes com o código existente, formata da mesma forma que o resto da equipe, da maneira que já está sendo feita. Consistência de muito mais importante do que bonita.

mattnz
fonte
Leia com mais atenção para que serve esse exemplo. Eu já mencionei isso: "Por exemplo, comentário estúpido:".
Kyrylo M
1
Eu entendi seu ponto. Tenho certeza de que você não ficará surpreso com quantos "comentários estúpidos" eu vi em código real, por isso mantenho meu post. o formato não importa, o conteúdo importa.
mattnz
3

Na medida do possível, escreva seu código de forma que os comentários sejam completamente estranhos. Adicione comentários apenas quando o código não puder ser escrito de forma a tornar óbvio um conceito importante.

Dave
fonte
2

Minha preferência é mantê-lo realmente simples. Eu evito todo tipo de formatação sofisticada. A principal razão para isso é que acho que o código fonte deve ser confortavelmente editável, mesmo com o editor de texto mais simples. Eu também nunca enrolei parágrafos de texto, mas deixei o editor fazer o invólucro suave (sem adição de novas linhas).

Kyrylo M
fonte
Eu nunca vi quebra automática nos comentários. Eu não acho que seja uma boa ideia, mas acho que tudo bem, desde que você a mantenha consistente.
Adam Byrtek
2

Costumo ver comentários como esse, e algumas ferramentas geram automaticamente dessa maneira:

/** 
 * This is an example, how to waste vertical space,
 * and how to use useless asterixes.
 */

Duas linhas a menos:

/** This is an example, how to spare vertical space,
    and how to avoid useless asterixes. */

IDEs e editores, marginalmente acima do nível do bloco de notas, são capazes de detectar comentários e imprimi-los em uma cor diferente. Não há necessidade de decorar o início da linha com asteriscos.

Você ainda poupa alguns bytes se usar uma guia para recuo.

Se você não usar um editor sofisticado, que renderize o comentário em tom cinza, a grande quantidade de asteriscos funcionará como ênfase e atrairá sua atenção, que é o oposto da coisa certa a fazer: ficar para trás.

Usuário desconhecido
fonte
Nesse caso, IDEs e editores podem usar a dobragem de código, se sua preocupação é salvar o espaço da tela. Se sua preocupação é salvar bytes, é necessário parar de codificar o Commodore 64 :) Mais seriamente, se você deseja salvar bytes (por exemplo, para o código do lado do cliente), um compilador ou um minificador fará isso por você enquanto você não precisará dos comentários na produção. O tamanho do código é importante, pois quanto mais código você tiver, maior a chance de erros ( sem dúvida ). Mas o tamanho total do arquivo não deve ser realmente uma preocupação em um processo moderno. Codifique o armazenamento ausente em um SCM e faça a manutenção em conformidade.
haylem
Se estiver trabalhando com um editor de baixa qualidade, asteriscos não atraem minha atenção, pois são comentários e seu alinhamento deixa claro. Se eu estivesse lendo o código de uma linguagem de script dinâmica, usar o seu estilo com um editor de baixa qualidade sem destaque seria mais difícil para meus olhos, pois levaria um tempo um pouco mais longo para processar se o que estou dizendo é ou não bloco de comentários inteiro ou alguma declaração de código estranhamente envolvida. Essa provavelmente é a pessoa e o resultado de seu hábito, mas é assim que eu o percebo.
Haylem 25/05
Não gosto de gastar meu tempo dobrando e desdobrando códigos. Eu concordaria com seu argumento de mercadoria, se os bytes tivessem uma única vantagem, mas eles não. Se o seu editor não possui destaque de código, compre um Commodore64. :) O argumento de indentação não é válido, porque se a indentação separar o comentário do código, ele também separará o código do comentário. Observe um pedaço maior de código comentado - um bloco de asteriscos funciona como uma ênfase.
usuário desconhecido
Como eu disse, pode ser pessoal. Mas pense bem: você realmente vê todos esses anúncios brilhantes e divertidos enquanto navega na Web? A maioria das pessoas não. Você apenas aprende a bloqueá-los, já que você os registrou como um padrão geral, pode facilmente bloquear sua mente. Funciona para mim para comentários de documentos. Sobre a dobra, pode ser entediante. Para Java, meu Eclipse está definido para dobrar muitas coisas por padrão, porque eu gosto de abrir meus arquivos Java e poder examiná-los como arquivos de cabeçalho C (sem a exibição de estrutura de tópicos). E uso o Mylyn para exibir apenas os bits nos quais trabalho.
Haylem 25/05
Sim, aprendi a bloqueá-los - com um plug-in, chamado bloqueador de anúncios. O Eclipse tem uma função fold, mas o gedit, que eu uso para programas pequenos e de arquivo único, não tem.
usuário desconhecido
2

Aqui está um "antipadrão" que encontrei em todo o código do meu trabalho: O uso de comentários como um "log de alterações"; é para isso que serve o log no seu sistema de controle de versão. O código está cheio de coisas como:

// 05-24-2011 (John Doe): Changed this method to use Foo class instead of Bar

e geralmente inclui o código antigo comentado (novamente, esse é o objetivo de um sistema VCS, portanto, não precisa estar no código após a gravação do novo código). Além disso, algo a evitar é repetir comentários como "Por que precisamos disso?" ou pior ainda, "Isso provavelmente deve ser renomeado" (porque existem ferramentas sofisticadas para renomear, portanto, no tempo que você levou para escrever esse comentário, você poderia ter renomeado a coisa). Mais uma vez, trato desses dois comentários regularmente, de acordo com:

// (John Doe) 05-24-2011 not sure why we are using this object?
FooBar oFooBar = Quux.GetFooBar(iFooBarID, bSomeBool);
oFooBar.DiscombobulateBaz();

// (John Doe). This method is poorly named, it's used for more 
// than just frazzling arvadents
public int FrazzleArvadent(int iArvadentID)
Wayne Molina
fonte
2
  1. Escolha um sistema de documentação como doxygen e atenha-se a ele. Continue verificando os documentos produzidos.
  2. Tente imaginar alguém novo na base de código entrando e lendo seus documentos. Eles poderiam começar com isso? Os estagiários são realmente bons para isso, escolha um novo com sua base de documentos existente e uma tarefa simples e veja até onde eles chegarão, se tropeçarem, com certeza tudo o que você disse para fazê-los funcionar novamente nos documentos.
  3. Faça dos comentários da documentação um ponto de verificação em seus processos de revisão.
Kyrylo M
fonte
1

Os leitores de código geralmente estão tentando responder a três perguntas:

  1. O que essa classe ou função faz? Se isso é difícil de responder, faz demais. Código difícil de documentar geralmente está errado.
  2. Como eu uso isso? Um exemplo pode ser bom o suficiente.
  3. Esse código é surpreendente. Porque você fez isso? Respostas mais prováveis: solucionar um bug em componentes de terceiros, porque a técnica óbvia se mostrou muito lenta

Tudo o resto deve ser expresso no código. Como escrever prosa, isso é uma arte e requer muita prática. A única maneira de saber se o seu código é compreensível é conseguir que alguém o leia. Quando eles não entenderem algo, não o explique verbalmente. Melhore o código. Adicione comentários como último recurso.

Se eu vir "comprimento duplo", perguntarei "Qual é a unidade de medida?" Não adicione um comentário. Mude o nome da variável. Se eu vir um bloco de código e disser "o que isso faz?", Não adicione um comentário. Extraia uma função com um nome significativo. Se você não pode extrair uma função porque precisaria de 17 argumentos, refatorar o código.

Kevin Cline
fonte