Documentação no código
O mais importante é usar os recursos de documentação no ambiente de desenvolvimento escolhido, o que significa pydoc para python, javadoc em java ou comentários xml em C #. Isso facilita a gravação da documentação ao mesmo tempo que o código.
Se você confiar em voltar e documentar as coisas posteriormente, talvez não consiga contornar isso, mas se fizer isso ao escrever o código, o que precisa ser documentado ficará em sua mente. O C # ainda tem a opção de emitir um aviso de compilação se a documentação XML estiver incompleta ou inconsistente com o código real.
Testes como documentação
Outro aspecto importante é ter uma boa integração e testes de unidade.
Frequentemente, a documentação concentra-se no que classes e métodos fazem isoladamente, ignorando como eles são usados juntos para resolver seu problema. Os testes geralmente os colocam em contexto, mostrando como eles interagem entre si.
Da mesma forma, testes de unidade frequentemente apontam explicitamente dependências externas através das quais as coisas precisam ser zombadas .
Também acho que, usando o desenvolvimento orientado a testes, escrevo um software que é mais fácil de usar, porque estou usando desde o início. Com uma boa estrutura de teste, tornar o código mais fácil de testar e fácil de usar geralmente é a mesma coisa.
Documentação de nível superior
Finalmente, há o que fazer sobre o nível do sistema e a documentação arquitetural. Muitos defenderiam escrever essa documentação em um wiki ou usar o Word ou outro processador de texto, mas, para mim, o melhor lugar para essa documentação é o código, em um formato de texto sem formatação que seja amigável ao sistema de controle de versão.
Assim como na documentação em código, se você armazena sua documentação de nível superior em seu repositório de código, é mais provável que a mantenha atualizada. Você também obtém o benefício de que, ao extrair a versão XY do código, também obtém a versão XY da documentação. Além disso, se você usar um formato compatível com VCS, significa que é fácil ramificar, diferenciar e mesclar sua documentação, assim como seu código.
Eu gosto bastante de reStructuredText (rst) , pois é fácil produzir páginas html e documentos PDF usando esfinge e é muito mais amigável que o LaTeX , mas ainda pode incluir expressões matemáticas do LaTeX quando você precisar delas.