Como documento meu código para revisão por tempo mínimo? [fechadas]

22

Desejo documentar meu código de forma que haja uma necessidade mínima de ler e navegar no código novamente meses depois.

Eu sei que existem diferentes tipos de documentação (no código fonte e fora, diagramas de sequência e assim por diante).

Eu só quero saber o que é uma maneira eficiente de documentar meu código, para que, quando alguns meses depois eu queira ver meu código, eu gaste menos tempo lendo o código e entendendo o fluxo de código.

Hamed_gibago
fonte
42
O melhor método para gastar menos tempo lendo o código posteriormente é escrever um código mais claro e compreensível .
Mael
A documentação depende do destino. Se você estiver dirigindo aos desenvolvedores, os comentários no código serão bastante úteis. Se você estiver dirigindo a analistas, os diagramas da visão geral também serão úteis. Se você estiver dirigindo-se a um público experiente em tecnologia, faça um guia do usuário.
LAIV
@ Laiv Bem, tendo em vista um desenvolvedor do meu próprio código e talvez outro código de desenvolvedor.
28718 Hamed_gibago #
A maior coisa é manter o código pequeno. Se o código necessário para implementar um item no seu sistema de rastreamento de problemas for grande, sua equipe poderá precisar aprender como dividi-lo um pouco mais para que a quantidade de código revisado não seja excessiva.
Berin Loritsch 8/0318

Respostas:

16

Devo admitir que não concordo com algumas das coisas que as outras respostas recomendaram, então vou jogar meus dois centavos;

Comentários

A documentação é extremamente útil para estranhos que leem seu código. Geralmente, muitas coisas não serão detalhadas o suficiente para serem lidas e entendidas imediatamente, e você deverá explicar o que está fazendo.

Edit : a discussão na seção de comentários apontou algo certo - o excesso de comentários geralmente é feito ao escrever um código incorreto .

Comentar o seu trabalho deve ser preciso e mínimo, mas, na minha opinião, definitivamente deve estar presente. Pelo menos um comentário para cada 15 linhas de código. Por exemplo, além dos blocos de código, adicione uma linha sobre o que você está fazendo:

def login(username: str, password: str, create_session: bool = True):

    # Filter the user we need from the database
    hash = md5(password)
    users = db.table("users", db_entities.USER)
    results = [x for x in users.query(lambda c: c.get("username") == username and c.get("password_hash") == hash)]


    if len(results) == 0:
        return None, None
    else:
        # Create a login session record in the database.
        if create_session:
            sessions = db.table("sessions", db_entities.SESSION)
            ses = sessions.new()
            ses.set("username", username) \
                .set("expiery", 31536000 + time.time())
            sessions.update(ses)
            return results[0], ses
        else:
            return results[0], None

Comentários mínimos que explicam o motivo e o que você está fazendo são muito úteis em todo o código. Eu não concordo com a resposta que afirma

Se eu encontrar um código contendo comentários, me preparo para o pior: o código provavelmente será ruim e, para ser honesto, os comentários provavelmente também serão ruins.

Muitas vezes, graciosamente, um bom código é documentado. É verdade que programadores ruins veem sua documentação como "Tudo bem, meu código é ruim, vamos adicionar algumas frases para deixar mais claro".

Sim, e embora isso ocorra bastante, também é verdade que bons programadores que escrevem código limpo também querem ter certeza de que retornam ao código e entendem por que desejam que sua função se comporte dessa maneira ou por que eles precisam disso. linha que parece um pouco redundante, etc ...

Sim, comentários que explicam coisas óbvias, comentários que não são claros, comentários que foram reunidos para garantir que "este código esteja documentado, sim, seja o que for", tem cheiro de código. Eles tornam a leitura do código mais difícil e irritante. (Adicionando um exemplo abaixo)

# Logging into Gmail when the module is imported
_client = login()
def get_client():
    global _client
    return _client

Exemplo de esclarecimento: "Merda, Sherlock. Efetua _client = login()login no serviço de correio? OMG!"

Mais esclarecimentos: o login()método não tem relação com o login()método do exemplo acima.

Mas os comentários que fazem corresponder aos padrões, explicar o porquê de, e não o how da, e responder as perguntas certas , são muito, muito ( muito ) votos.

Comentários embutidos

Uma coisa que você NÃO deveria (e se eu pudesse escrever isso maior, faria) é escrever seus comentários na mesma linha do código. Faz comentários muito específicos de linha, o que perde completamente o objetivo de comentar seu código.

Por exemplo, comentários inline incorretos:

outer = MIMEText(details["message"]) # Constructing a new MIMEText object
outer["To"] = details["to"] # Setting message recipient
outer["From"] = "xAI No-Reply" # Setting message sender
outer["Subject"] = details["subject"] # Setting message subject
outer.preamble = "You will not see this in a MIME-aware mail reader.\n" # I don't know what I'm doing here, I copied this from SO.
msg = outer.as_string() # Getting the string of the message
_client = details["client"] # Assigning the client
_client.sendmail(SENDER, details["to"], msg) # Sending the mail

Seria muito mais fácil ler e entender esse código sem os comentários, que o tornam confuso e ilegível.

Em vez disso, os comentários dentro do seu código devem ser colocados acima dos blocos do código e devem responder às perguntas importantes que podem surgir durante a leitura do bloco de código.

# Constructing the email object with the values 
# we received from the parameter of send_mail(details)
outer = MIMEText(details["message"])
outer["To"] = details["to"]
outer["From"] = "xAI No-Reply"
outer["Subject"] = details["subject"]
outer.preamble = "You will not see this in a MIME-aware mail reader.\n"
msg = outer.as_string()

# Sending the mail using the global client (obtained using login())
_client = details["client"]
_client.sendmail(SENDER, details["to"], msg)

Muito mais claro, certo? Agora você também sabe que precisa usar a login()função e fornecer os parâmetros send_mail()com tudo o que usou. Ajuda um pouco, mas ainda falta uma coisa.

Documentação de função

Tem sido amplamente discutido. Você deve sempre informar seus leitores sobre o que é sua função, por que e o que ela faz. Como isso acontece, isso não pertence à documentação, mas talvez às notas de rodapé da função.

Você deve descrever claramente o que espera que seus parâmetros sejam e se deseja que eles sejam obtidos / criados em um método específico. Você deve declarar qual deve ser a sua função, qual é o seu uso, etc.

Novamente, essa é minha opinião e metodologia ao escrever meu código. Não apenas essas, mas essas são apenas algumas das coisas com as quais não concordo com as outras respostas. Ah, e é claro, não apenas os comentários leem seu código, mas também o próprio código. Escreva um código limpo, compreensível e sustentável . Pense em seu futuro enquanto codifica ;-)

Yotam Salmon
fonte
5
Não concorde com um exemplo dado - em vez de escrever muitos comentários em uma função enorme, você deve compor a partir de muitas funções menores com nomes descritivos, que atuarão como comentários. Sem o risco de ficar fora de sincronia com o que o código está realmente fazendo.
precisa saber é o seguinte
6
Finalmente alguma sanidade. Extrair cada parte do código que poderia usar um comentário em sua própria função é como você acaba com milhares de funções espalhadas por centenas de arquivos.
user369450
2
Esse segundo exemplo é adorável.
Lightness Races com Monica no dia
7
Os comentários no segundo exemplo são muito detalhados. Alguns deles (por exemplo, "encontramos alguma coisa?") Apenas repetem o que o código diz e seria melhor removido. Por outro lado, você pode obter mais legibilidade ao refatorar, como tornar (stream.is_empty ()) a condição do loop ou mover a verificação dos valores de aceitação para fora.
Frax
3
@cpburnz, "Eu tive que pesquisar muitos projetos herdados e bibliotecas de terceiros sem nenhum comentário de código para apreciar comentários que explicam o que está acontecendo e por quê". exatamente o que quero dizer o tempo todo: existem comentários para explicar o código de porcaria. Como a pergunta é "como faço para escrever um código tão fácil de ler", então claramente esta resposta está errada, pois se concentra em escrever comentários para explicar códigos incorretos, em vez de escrever bons códigos em primeiro lugar.
David Arno
55

A melhor documentação da IMO é a documentação que você realmente não precisa. Eu também odeio escrever documentação e comentários.

Com isso dito:

  • Escolha nomes legíveis e falantes. Não use n, mas, numberOfItemsFoundpor exemplo.
  • Não coíbe de armazenar partes de um cálculo em uma variável constante, em vez de colocar tudo em uma linha.
  • Mova tarefas parciais de ramificações para suas próprias funções (em linha), se você as estiver reutilizando ou se a função pai se tornar longa e tediosa de seguir.
  • Seja mais elaborado e otimize o código apenas sobre a legibilidade, onde é realmente necessário.
Mario
fonte
19
Aqui está uma boa métrica para a documentação (link obrigatório).
Neil
4
Isso também deve estar na lista: explique no código por que você está fazendo as coisas que está fazendo.
T3chb0t 08/0318
4
numberOfItemsFoundé bastante detalhado; muito detalhado também é um problema.
Matthieu M.
6
@ MatthieuM., Raramente é um problema "muito detalhado" com nomes no código. Muito conciso ou enigmático é um problema muito comum.
David Arno
25

Trate seu código como documentação

Seu código é sua documentação principal. Descreve precisamente o que o aplicativo resultante, a biblioteca ou o que quer que seja, realmente faz. Como tal, qualquer tentativa de acelerar o entendimento desse código deve começar pelo próprio código.

Há muitos escritos sobre como escrever código legível, mas alguns dos pontos principais são:

  • não confie nos comentários para explicar o código incorreto, melhorar o código e se livrar dos comentários,
  • escreva curtas funções, métodos, classes, etc.
  • use nomes apropriados para o contexto (por exemplo, né bom para um loop, nomes descritivos mais longos são necessários para itens com maior escopo),
  • trate os nomes das funções como se fossem comentários, por exemplo, não use UpdtTblcom um comentário explicando que ele atualiza a tabela com as regras fornecidas quando UpdateTableContentsWithSuppliedRulespode ser usado como o nome,
  • evitar mutabilidade. Sempre que você altera o conteúdo de uma variável, aumenta a complexidade do código. Atribua esse novo valor a uma nova variável (com um bom nome) sempre que possível.
  • por último e mais importante, evite códigos "inteligentes". O único código inteligente é o código fácil de ler. Se você escrever um pouco complexo de código e se achar "uau, não sou inteligente aqui?", É quase garantido que a resposta seja "não, você não é".

Torne-se melhor na leitura de código

Ler código, independentemente de quão simples seja, é uma habilidade aprendida. Ninguém é naturalmente bom em ler códigos. É preciso prática; muita prática. Por exemplo, acesse o Github ou o que for e leia o código das bibliotecas que você usa, em vez de apenas usá-las. Encontre o código para ler e ler.

Comentários são um cheiro de código

Somente então chegamos a outros tipos de documentação. Em primeiro lugar, como afirmado anteriormente, evite comentários. Se eu encontrar um código contendo comentários, me preparo para o pior: o código provavelmente será ruim e, para ser honesto, os comentários provavelmente também serão ruins. É improvável que alguém que não consiga se comunicar bem através do código seja capaz de se comunicar melhor através da linguagem natural.

Cuidado com a documentação da API gerada automaticamente

Além disso, tenha cuidado com a documentação da API gerada automaticamente. Se eu tiver que recorrer a ler esses documentos, será porque seu código é muito difícil de ler. Novamente, simplifique o código e eu posso ler isso diretamente.

Os testes também são documentos

Testes também são documentação. Portanto, não trate seus testes de unidade como uma tarefa árdua. Trate-os como uma maneira de se comunicar com os outros (seus seis meses posteriores sendo incluídos aqui) sobre como o código funciona e se destina a ser usado.

Faça desenhos se ajudar

Se você gosta da UML, encontre uma boa ferramenta e gere diagramas UML a partir do seu código. Apenas nunca, jamais, jamais tente usá-lo para gerar código. Não é bom como uma ferramenta de design e, como resultado, você acabará com um código horrível.

Tenha um documento de exibição "1000 pés"

Por fim, escreva para si mesmo um documento de visão geral. O que o aplicativo faz? Como isso acontece? A que outros sistemas ele se conecta? Coisas assim. Não tente descrever a estrutura de código aqui. Deixe o código fazer isso. Deixe este documento lembrá-lo por que você escreveu o código em primeiro lugar.

David Arno
fonte
14
Concordo com todo o seu argumento, exceto que os comentários têm seu lugar. Embora eu concorde que não há sentido em comentários como add 1 to i, os comentários devem explicar por que o código faz o que faz. Por exemplo, o código if (!something.Exists()) {...}pode usar um comentário do tipo: // something exists only when (explanation of the broader scenario).
317 Jonathan
16
Todos nós vimos nosso quinhão de // increment x x++;comentários inúteis, mas é errado jogar o bebê fora na água do banho e declarar que os comentários são sempre ruins. Por exemplo, comentários do formulário // this case should never happen because xyz throw exception "unreachable".
angrydust
7
Lista muito boa. Mas como @ Jonathan. Eu não concordo com os comentários. Algumas vezes, porém, é necessário considerar erros em estruturas de terceiros. Embora isso possa ser refatorado em sua própria função, ainda é bom deixar um pouco de descrição do motivo pelo qual a solução alternativa (número do bug ou nome do bug / descrição do bug) é necessária.
magu_
16
@ DavidDArno Mas você não pode fazer isso para um comentário explicando por que algo não foi feito. Like //XXX: Not using straight-forward method Foo here because .... Tais comentários podem ser imensamente valiosos, mas são impossíveis de transmitir com o código por razões óbvias.
cmaster
7
Eu gosto ainda mais dramático: todo comentário é uma falha em se expressar bem no código . Por exemplo, eu tenho um comentário de 4 linhas em um método, explicando a solução alternativa para um bug de terceiros. Não consegui expressar isso muito bem no código, então está em um comentário . Eu diria que melhorou a legibilidade, porque duvido que alguém goste de rolar horizontalmente para ler um nome de método muito longo e muito descritivo. "Comentários são um cheiro de código" - sim, mas precisamos lembrar que nem tudo que cheira é merda.
R. Schmitz
5

Forneça uma carta de apresentação

A menos que você esteja em um domínio muito técnico, a maioria das perguntas sobre o código não será sobre o 'como', mas sobre o 'por que' ou o 'o que'.

Dessa forma, a maneira de impedir que as pessoas precisem procurar no seu código é escrever uma breve descrição dele. A vantagem disso é que você pode compilar uma visão geral das descrições com bastante facilidade e isso é muito mais acessível. (Mesmo para pessoas que não / não têm permissão para ver o código).

Mesmo que as pessoas sejam técnicas, a carta de apresentação deve oferecer orientação sobre onde eles devem procurar algo.

Pontos extremamente minimalistas simples :

  1. Introdução, por que esse código (base) existe
  2. Que função o subconjunto de código cumpre
  3. Onde está o código (nome do script, por exemplo)

Exemplo

  1. Esse conjunto de scripts raspa o StackOverflow e eleva as respostas de Dennis Jaheruddin
  2. uma. Esse script é responsável por analisar o html e analisar se é o usuário certo
  3. uma. O script pode ser encontrado em: ScrapeAndVote / RecognizeDennis.scr
Dennis Jaheruddin
fonte
1

O maior ganho de velocidade que eu normalmente ganho ao criar commits separados, cada um representando uma etapa intermediária que compila e funciona.

Portanto, se eu tiver que introduzir um novo parâmetro em uma função para implementar um recurso específico, existe um commit que não faz nada além de adicionar o parâmetro na declaração, na definição e em todos os sites de chamada. Em seguida, o próximo commit introduz a funcionalidade e o terceiro atualiza os sites de chamada que fazem uso do novo recurso.

Isso é fácil de revisar, porque as alterações puramente mecânicas podem ser examinadas rapidamente e depois sair do caminho.

Da mesma forma, se você reformatar o código, esse sempre deve ser um commit separado.

Simon Richter
fonte
1

Embora haja um ou dois pontos aparentes de desacordo entre as respostas existentes, mesmo que com ênfase, tentarei resumir os conselhos usuais de uma maneira que deixe claro de onde todos estão vindo:

  1. Em primeiro lugar, escreva um código limpo; qualquer outra "documentação" se cuidará depois disso. O código limpo é um conjunto de princípios a serem aprendidos em primeiro lugar: classes de responsabilidade única, métodos curtos que fazem uma coisa, bons nomes de variáveis ​​e métodos, melhores nomes de classe / tipo do que esses , concentrando-se em metáforas (por exemplo, chame um MultiButtSupporter de refrigerante), testes de unidade para indicar requisitos, SECO, SÓLIDO, um paradigma consistente e assim por diante.
  2. O código revela como o código funciona; comentários revelam por que o código funciona. Por exemplo, explique um +1 com "impede um erro de 1 em 1" ou alguma fórmula complicada com "derivado neste livro ou página da web".
  3. O que quer que você esteja fazendo com os comentários, o ponto 1 acima pode muito bem alcançar isso em código limpo. Veja os comentários como falhas / males necessários ou até mentiras se, com o tempo, ficarem fora de sincronia com o código, pois ambos são editados. Os comentários não devem compensar códigos mal escritos, porque por que os comentários seriam escritos com mais talento ou cuidado do que o código?

Por outro lado, se alguma coisa eu provavelmente errei demais para o outro lado, quase nunca usando comentários. Seus revisores de código informarão se você tem o equilíbrio no lugar errado, mas se você fizer um esforço consciente para seguir o plano de três pontos acima, provavelmente estará próximo do ideal de qualquer maneira.

JG
fonte
2
Como um comentário "impede um erro de 1 em 1" é diferente de um comentário que diz "o +1 não é um erro de digitação" ou "não estou ciente de um erro de erro no meu programa"? (Os comentários úteis geralmente se referem a algo maior que +1 no código-fonte ou a algo fora do código-fonte.) Portanto, ainda resta "derivado deste livro ou página da web" como um exemplo válido e realmente ótimo no seu ponto 2. Então, o ponto 3 parece sugerir que você pode expressar "derivado deste livro ou página da web" usando um código suficientemente limpo, sem nenhum comentário; uau, eu gostaria de ver isso em ação.
Jirka Hanika #
@JirkaHanika Talvez um por um tenha sido um mau exemplo. Quanto a 3, o que eu quis dizer foi "cada um pode" em vez de "talvez cada um"; então não, acho que o código sozinho não pode esclarecer essas coisas. (Bem, você poderia tentar gaussianFromThisTextbookNamesApproximation como um nome de variável, mas isso é uma má idéia!)
JG