- Estou tentando melhorar minhas habilidades de design de software e recebi a recomendação de estudar codebases existentes e bem projetados
- Entre os codebases publicamente acessíveis, queria saber quais são considerados o padrão-ouro em design de software
1. Codebases recomendados
- Projetos grandes/de referência
- Git, Postgres, CPython
- o "lieutenants model" do Linux Kernel
- UNIX v6, BSDs
- Frameworks/bibliotecas
- Sistemas/servidores
- Jogos/casos especiais
- Materiais educacionais/de aprendizado
- Outros
- Monocypher (biblioteca de criptografia)
- implementação da linguagem Tcl
2. Leitura de código vs. estudo de documentação/design
- Limites do código por si só
- Um codebase mostra a implementação, mas esconde a intenção do design e os trade-offs
- Importância da documentação de design
- Registros de decisão como ADR (Architectural Decision Records), RFCs do Rust e PEPs do Python são muito mais úteis para aprender design
- Escrever documentos de design por si só também pode servir como treinamento
- Livros e leituras recomendadas
3. Abordagem de aprendizado centrada na prática
- Experiência e tentativa e erro
- Design se aprende passando repetidamente por problemas e aprendendo como evitá-los
- Só ler código não basta; o aprendizado acontece no processo de escrever, falhar e resolver esses fracassos
- Aprendizado guiado por interesse
- Você aprende mais profundamente ao criar projetos pelos quais realmente tem interesse
- Baixo custo do fracasso
- Em software, o custo de falhar é menor do que em engenharia física, então aprender tentando e errando é especialmente eficaz
4. Debate sobre a natureza da engenharia de software
- Visão de engenharia imatura
- Se cinco engenheiros se reúnem e produzem cinco soluções diferentes, isso seria um sinal de imaturidade como disciplina de engenharia
- Visão de afinidade com experimentação
- Software tem menos restrições, então admite várias soluções; ao contrário da engenharia física, não há uma resposta fixa
- Fronteira entre arte e engenharia
- Design também pode ser um ato artístico com elementos estéticos, mas continua sendo engenharia na medida em que atende requisitos funcionais
- Software fica entre a flexibilidade artística e o rigor da engenharia
5. Métodos alternativos de aprendizado
- Analisar código ruim
- Não é só código bem projetado: corrigir codebases ruins também gera um grande efeito de aprendizado
- Aprender com o próprio codebase
- O codebase interno da sua equipe foi citado como uma das fontes de aprendizado mais valiosas
- Mas, se o código do time for ruim, vale combinar isso com exemplos externos
- Aprendizado adaptado ao domínio
- Ler codebases parecidos com os problemas que você quer resolver é a abordagem mais eficaz
Principais insights
- Codebases bem projetados ajudam, mas o aprendizado precisa caminhar junto com a compreensão da intenção do design e com tentativa e erro
- Mais do que a leitura do código em si, documentos de design e registros de decisão são os principais materiais de estudo
- Projetos de alta qualidade e bem conhecidos (Git, Postgres, CPython, biblioteca padrão do Rust etc.) têm alto valor de aprendizado
- Além de código bom, aprender com código ruim e com o próprio código tende a ser mais prático no longo prazo
Resumo dos principais comentários
Recomendações de codebases de destaque (CraigJPerry)
- Servidor de e-mail Postfix
- Sua arquitetura focada em segurança já mostrava uma estrutura parecida com microservices antes mesmo de o conceito existir
- Enquanto microservices modernos focam na distribuição em grandes organizações, o Postfix foi projetado para segurança e simplicidade
- Spring Framework
- Reflete uma cultura que considera profundamente as necessidades de desenvolvedores Java em ambientes enterprise
- Dá para aprender uma abordagem de design centrada no usuário
- Git
- Depois de entender o banco de dados de objetos (blobs, trees, commits) e o conceito de referências, o restante é uma expansão gradual
- A expansão consistente de conceitos centrais é apresentada como um bom exemplo de design
- Varnish
- Além de ser um reverse proxy de alto desempenho, tem um codebase organizado a ponto de servir também como ferramenta de aprendizado
- Linux Kernel Lieutenants Model
- Não é um codebase, mas vale como referência de modelo de gestão de software em larga escala
- Mais do que simplesmente "código bem projetado", são casos em que as decisões de design deixam uma impressão forte
Ênfase no aprendizado com codebases de trabalho real (crystal_revenge)
- O maior valor de aprendizado pode vir do codebase da sua própria equipe
- No processo confuso de conectar requisitos reais à implementação, você vivencia ao mesmo tempo boas e más decisões
- Entre as restrições do mundo real, o fator mais importante é a pressão de tempo, e o essencial é aprender a equilibrar design ideal e realidade
- Bom software é aquele que resolve as necessidades do usuário, e a experiência repetida ensina a projetar com mais chance de sucesso
Discussões anteriores e links de referência (sprobertson)
- O mesmo tema já apareceu várias vezes no HN
Código vs. documentos de design (alphazard)
- Um codebase é apenas o resultado da implementação, não o design em si
- Para aprender design, escrever documentos de design é mais eficaz
- Os documentos precisam ser claros o suficiente para que outra pessoa consiga implementá-los exatamente
- Listar alternativas e registrar por que foram descartadas serve como evidência das considerações de design
- Um bom designer é alguém que considera um espaço de design mais amplo e escolhe o ponto apropriado
Ênfase em entender o sistema como um todo (RossBencina)
- O processo de compreender um codebase inteiro é muito valioso
- Isso treina não só a leitura de código bem projetado, mas também a visão do quadro geral do sistema
- Visualizar relações com diagramas como UML pode ajudar
- Abordagem de aprendizado:
- Ler o código de softwares parecidos com aquilo que você está desenvolvendo é eficaz
- Recomenda-se começar por código de domínios que você já conhece bem (frameworks web, servidores web, biblioteca padrão do Python, VSCode etc.)
- No início, é melhor abordar programas pequenos e domínios familiares
Critérios para um bom design (mamcx)
- Um bom design mostra objetivos e ideias, enquanto o codebase revela o grau em que isso foi implementado
- Bom design não é apenas um rótulo como "rápido" ou "seguro", mas deve incluir considerações concretas e registro de trade-offs
- Exemplos: essas características podem ser observadas em Erlang, no Pascal inicial e no design de vários RDBMS
- A biblioteca padrão do Rust é um ótimo material de estudo porque enfatiza segurança e consistência, e tanto o código quanto a documentação refletem isso fielmente
Decisões de design invisíveis (ben30)
- Ao olhar para um codebase bem projetado, a parte mais importante é aquilo que não aparece
- Decisões de ausência, como excluir complexidade, evitar abstrações desnecessárias e rejeitar certos padrões, são o ponto central
- Para complementar isso, vale usar ADR (Architectural Decision Records)
- Eles registram alternativas, motivos para rejeitá-las e fundamentos da escolha, preservando o contexto
- Isso ajuda muito tanto futuros mantenedores quanto ferramentas de IA
- Ao estudar, é eficaz observar não só o código, mas também projetos que vêm acompanhados de documentos de decisão de design, como ADR, RFC e PEP
Ainda não há comentários.