Como tornar uma base de código grande mais fácil de entender para novos programadores

102

Suponha que estou desenvolvendo um projeto relativamente grande. Eu já documentei todas as minhas classes e funções com o Doxygen, no entanto, tive a idéia de colocar "notas do programador" em cada arquivo de código-fonte.

A ideia por trás disso é explicar em termos leigos como uma classe específica funciona (e não apenas por que como a maioria dos comentários faz). Em outras palavras, para dar aos colegas programadores uma visão diferente de como funciona uma aula.

Por exemplo:

/*
 * PROGRAMMER'S NOTES:
 *
 * As stated in the documentation, the GamepadManager class 
 * reads joystick joystick input using SDL and 'parses' SDL events to
 * Qt signals.
 *
 * Most of the code here is about goofing around the joystick mappings.
 * We want to avoid having different joystick behaviours between
 * operating systems to have a more integrated user experience, since
 * we don't want team members to have a bad surprise while
 * driving their robots with different laptops.
 *
 * Unfortunately, we cannot use SDL's GamepadAPI because the robots
 * are interested in getting the button/axes numbers, not the "A" or
 * "X" button.
 *
 * To get around this issue, we created a INI file for the most common 
 * controllers that maps each joystick button/axis to the "standard" 
 * buttons and axes used by most teams. 
 *
 * We choose to use INI files because we can safely use QSettings
 * to read its values and we don't have to worry about having to use
 * third-party tools to read other formats.
 */

Seria uma boa maneira de tornar um projeto grande mais fácil para novos programadores / colaboradores entenderem como ele funciona? Além de manter um estilo de codificação consistente e uma organização de diretório "padrão", existem "padrões" ou recomendações para esses casos?

    
por Alex Spataru 01.08.2015 / 00:33
fonte

10 respostas

135

Isso é incrível. Desejo que mais desenvolvedores de software tenham tempo e esforço para fazer isso. Isso:

  • Afirma em inglês simples o que a turma faz (ou seja, é responsabilidade),
  • Fornece informações suplementares úteis sobre o código sem repetir textualmente o que o código já diz,
  • Descreve algumas das decisões de design e por que elas foram feitas e
  • Destaca algumas das armadilhas que podem acontecer à próxima pessoa que estiver lendo seu código.
Infelizmente, muitos programadores entram no campo de "se o código está escrito corretamente, não deveria ser documentado". Não é verdade. Existem muitos relacionamentos implícitos entre classes de código, métodos, módulos e outros artefatos que não são óbvios apenas lendo o próprio código.

Um programador experiente pode criar cuidadosamente um projeto com uma arquitetura clara e facilmente compreensível que seja óbvia sem documentação. Mas quantos programas como esse você realmente viu?

    
por 01.08.2015 / 00:42
fonte
35

A chave para trabalhar com uma grande base de código é não ter que ler toda a base de código para fazer uma alteração. Para permitir que um programador encontre rapidamente o código que ele está procurando, o código deve ser organizado e a organização aparente. Ou seja, cada unidade lógica no código, do executável, da biblioteca, do namespace, até a classe individual, deve ter uma responsabilidade claramente aparente. Eu não apenas documentaria os arquivos de origem, mas também os diretórios em que eles residem.

As anotações do seu programador também fornecem informações sobre decisões de design. Embora isso possa ser uma informação valiosa, eu a separaria da declaração de responsabilidade (para permitir que o leitor escolha se ele quer ler sobre a responsabilidade da classe ou sua justificativa de design) e mova-a o mais próximo da fonte que descreve quanto possível, para maximizar a chance de a documentação ser atualizada quando o código for (a documentação só é útil se pudermos confiar em sua precisão - a documentação desatualizada pode ser pior do que nenhuma!).

Dito isso, a documentação deve permanecer em DRY, ou seja, não repetir informações que poderiam ter sido expressas em código ou já foram descritas em outro lugar (frases como "os estados da documentação" são um sinal de alerta). Em particular, os futuros mantenedores serão apenas proficientes na linguagem de programação do projeto, pois estão em inglês; parafrasear a implementação nos comentários (o que eu vejo com muita frequência quando as pessoas estão orgulhosas de sua documentação) não tem nenhum benefício, e é provável que divergir da implementação, em particular se a documentação não estiver próxima do código que ela descreve.

Finalmente, a estrutura da documentação deve ser padronizada em todo o projeto para que todos possam encontrá-la (é uma confusão real dos documentos do Peter no rastreador de erros, Sue no wiki, Alan no readme e John no código-fonte. ..).

    
por 01.08.2015 / 11:26
fonte
13

Eu não concordaria que essa seja uma abordagem muito boa, principalmente devido a

  1. Ao refatorar seu projeto, mudar os métodos, a documentação é interrompida.

  2. Se a documentação não for atualizada corretamente, isso resultará em mais confusão do que ajuda na compreensão do código.

Se você tiver testes de unidade para cada teste de método / integração de cada módulo, seria uma documentação própria mais fácil de ser mantida e mais fácil de entender em comparação aos comentários de código.

Sim, ter uma estrutura de diretórios adequada ajudará definitivamente.

    
por 02.08.2015 / 11:55
fonte
7
Sou pessoalmente um fã de um documento de design de alto nível - de preferência escrito ANTES de qualquer código - que fornece uma visão geral do design e uma lista de classes e recursos. Um design de cima para baixo simplifica bastante as coisas - o seu pode ser "mecanismo de jogo - > hardware - > controladores - > joystick"; assim, um novo programador disse que "corrija o botão 'a' no 'controlador xyz" pelo menos saberia por onde começar a procurar.

Muitas linguagens modernas tendem a dividir o código em centenas de arquivos minúsculos, portanto, apenas encontrar o arquivo correto pode ser um desafio até mesmo em um projeto moderado.

    
por 01.08.2015 / 10:58
fonte
5

Se o código-base for grande - eu tento fornecer um documento de design que mapeie os principais elementos de seu design e a implementação . A intenção aqui não é detalhar qualquer uma das classes usadas, mas fornecer uma chave para o código e o pensamento que entrou no design. Ele fornece um contexto abrangente para o sistema, seus componentes e sua aplicação.

Coisas para incluir no documento de design são:

  • Arquitetura de aplicativos
  • Estrutura de código lógico
  • Fluxos de dados
  • Padrões-chave usados e a motivação por trás de seu uso
  • Estrutura de código fonte
  • Como criá-lo (isso oferece insights sobre dependências implícitas e estrutura de origem de código físico)

Em seguida, documentação para as classes e funções / métodos deve ser concluída conforme apropriado . Em particular, a API pública; deve ficar claro quais são os seguintes em todos os casos;

  • Pré-condições
  • Efeitos
  • Invariantes
  • Condições de exceção (lances)
por 03.08.2015 / 11:02
fonte
4

A regra mais importante que encontrei para tornar mais fácil para os novos desenvolvedores entenderem uma base de código é o acordo perfeito é caro.

Se novos desenvolvedores precisam entender perfeitamente o sistema em que estão trabalhando, isso evita todas as oportunidades de aprendizado no trabalho. Eu acho que as notas do programador são um excelente começo, mas eu iria mais longe. Tente escrever código que, se abordado de novo, permita que um desenvolvedor descubra o que está fazendo em tempo real, em vez de exigir que ele aprenda antes de fazer isso. Pequenas coisas como afirmações para casos que você conhece nunca podem ocorrer, junto com comentários explicando por que a afirmação é válida, percorrer um longo caminho. O mesmo acontece com o código de escrita que falha graciosamente em vez de segmentar se você fizer algo errado.

    
por 02.08.2015 / 08:51
fonte
3

Eu tenho visto grandes classes com documentação, e depois de ler a documentação eu não tenho idéia do que esta classe deve ser boa e porque alguém a usaria! E, ao mesmo tempo, eu precisava de alguma funcionalidade e tinha absoluta certeza de que deveria haver uma turma para lidar com ela, e não conseguia encontrá-la em lugar nenhum - porque não havia documentação que me levasse do que eu precisava para a aula Fazendo.

Então, a primeira coisa que eu gostaria de ter na documentação é apenas algumas frases que uma classe faz e por que eu gostaria de usá-la. Os comentários da pergunta original estão indo muito bem a esse respeito. Depois de ler esses comentários, se eu tivesse um joystick que não funcionasse bem, porque não posso interpretar os valores que ele entrega, eu saberia qual código verificar.

    
por 02.08.2015 / 22:21
fonte
0

Semelhante ao que @meriton disse, divida o código em componentes separados. Melhor ainda, divida a base de código em pacotes (JARs, gems, eggs, whatever) separados para deixar ainda mais claro como os componentes são separados. Se houver um bug, um desenvolvedor só precisa encontrar o pacote onde o bug está, e (esperançosamente) apenas consertá-lo lá. Para não mencionar, é mais fácil fazer testes de unidade e você pode aproveitar o gerenciamento de dependências.

Outra solução: tornar a base de código menor. Quanto menos código houver, mais fácil será entender. Refatore o código não utilizado ou duplicado. Use técnicas de programação declarativa . Isso exige esforço, é claro, e muitas vezes não é possível ou prático. Mas é um objetivo digno. Como Jeff Atwood escreveu: O melhor código não é nenhum código

    
por 08.08.2015 / 16:39
fonte
-1

Para sistemas complexos, pode valer a pena não apenas documentar cada arquivo, mas suas interações e hierarquia, e como o programa é estruturado e por quê.

Por exemplo, um motor de jogo é geralmente bastante complexo e é difícil decidir o que chama depois de cem camadas de abstração. Pode valer a pena criar um arquivo como "Architecture.txt" para explicar como e por que o código é estruturado assim e por que existe essa camada de abstração de aparência sem sentido.

    
por 02.08.2015 / 13:25
fonte
-7

Isso pode ser em parte porque é difícil para um único programador escrevê-lo, pois cada indivíduo entende apenas sua parte do projeto.

Às vezes, você pode obter essas informações a partir das anotações do gerente do projeto, mas isso é tudo o que você receberá, pois elas raramente reescreverão suas anotações nesse formato.

    
por 01.08.2015 / 07:17
fonte