2.0 Introdução à Parte 2: Programação de software
A Parte 2 trata do ofício diário de escrever software que muitas pessoas consigam ler, alterar e em que possam confiar ao longo de uma vida longa. A Parte 1 estabeleceu as fundações de como as equipes se organizam e decidem. Esta parte se volta para o próprio código: as convenções que você segue, a forma como molda designs e interfaces, como testa e revisa o seu trabalho, como gerencia o histórico do código-fonte e como põe as coisas por escrito. São as práticas que separam uma base de código que acelera a entrega de uma que luta contra cada mudança.
Numa equipe grande, o ofício não é questão de gosto pessoal. É como você se coordena. Quando centenas ou milhares de engenheiros, terceirizados e sucessores mexem nos mesmos sistemas, convenções compartilhadas e contratos claros são o que permite a todos trabalhar em paralelo sem colisões constantes. Lembre-se de que o código é lido muito mais vezes do que escrito, e boa parte dessa leitura acontece anos depois, por pessoas que você nunca vai conhecer.
Em contextos corporativos e governamentais, o que está em jogo sobe ainda mais. Os sistemas costumam sobreviver a seus autores por uma década ou mais. A regulamentação e a auditoria exigem evidências documentadas de controle. O conhecimento precisa se transferir através da rotatividade de pessoal e das fronteiras contratuais. Por isso os capítulos aqui tratam a qualidade não como heroísmo, mas como uma propriedade projetada e em grande parte automatizada da forma como toda a equipe trabalha.
Capítulos desta parte
2.1 Padrões de codificação e estilo: Convenções compartilhadas e impostas automaticamente para nomenclatura, formatação e idiomas de programação que permitem que muitos autores escrevam como se um único autor cuidadoso tivesse escrito, para que os revisores gastem a atenção no design e não no estilo.
2.2 Princípios de design de software: Heurísticas como SOLID (cinco princípios de design orientado a objetos), DRY (não se repita), acoplamento e coesão e Domain-Driven Design (modelar o software na linguagem do domínio de negócio), tratadas como ferramentas com um domínio de aplicabilidade e modos de falha conhecidos, e não como leis a obedecer.
2.3 APIs e design de interfaces: Projetar os contratos pelos quais sistemas e equipes se encontram, para que equipes independentes possam mudar seus internos sem quebrar os consumidores nem forçar implantações em sincronia.
2.4 Estratégia de testes: Escolhas deliberadas sobre o que testar, em que nível e com que grau de confiança, construindo uma rede de segurança rápida e confiável que permita a uma grande organização implantar com frequência e com segurança.
2.5 Revisão de código e colaboração: Examinar as mudanças antes de serem integradas para pegar defeitos, espalhar conhecimento, impor padrões e satisfazer controles de conformidade, mantendo a revisão rápida e construtiva em vez de cerimonial.
2.6 Controle de versões e gestão de código-fonte: O sistema de registro de cada mudança e a disciplina de ramificação, de repositório e de commits que mantém a linha principal pronta para lançamento, o histórico legível e a trilha de auditoria íntegra.
2.7 Documentação: O conhecimento escrito, de guias de primeiros passos a runbooks (procedimentos operacionais passo a passo) e registros de decisão, que defende contra o risco de dependência de pessoas-chave, acelera a integração e transfere o entendimento ao longo dos anos e das fronteiras contratuais.
2.8 Requisitos de software: Elicitar, especificar, validar e gerenciar o que o software deve fazer e com que qualidade, com a rastreabilidade que o trabalho regulamentado e governamental exige.
2.9 Construção de software: O ofício de construir software que funciona: minimizar a complexidade, construir para verificação e mudança, programação defensiva e reutilização disciplinada.
2.10 Gestão de configuração de software: Identificar, controlar e auditar cada item de configuração (qualquer artefato cujas versões precisem ser rastreadas e controladas) e cada mudança, para que os lançamentos sejam reproduzíveis e a trilha de auditoria seja íntegra.
2.11 Qualidade de software: A qualidade como uma propriedade gerenciada mais ampla que o teste: modelos de qualidade, garantia versus controle, medição, gestão de defeitos e o custo da qualidade.
2.12 Modelos e métodos de software: Quando e como modelar, abrangendo modelos estruturais e comportamentais, métodos formais (especificação e verificação de base matemática), prototipagem e métodos ágeis, e quando a modelagem é desperdício.
2.13 Fundamentos de computação, matemática e engenharia: Os fundamentos duradouros por baixo da prática: algoritmos e estruturas de dados, lógica e probabilidade e o método empírico da engenharia.
2.14 Estrutura de projetos e repositórios: Convenções consistentes para organizar uma solução e seu repositório, incluindo pastas padrão, um README como ponto de entrada e configuração compartilhada, para que qualquer engenheiro consiga navegar por qualquer base de código.
2.15 Depuração e resolução de problemas: Encontrar e corrigir defeitos como uma prática disciplinada e ensinável de reproduzir, isolar por busca binária, formular e testar hipóteses e registrar cada correção como um teste de regressão, em vez de adivinhação e mudanças a esmo.
2.16 Engenharia de desempenho: Tornar o software rápido o bastante de propósito, definindo orçamentos de desempenho, medindo e fazendo profiling antes de otimizar, entendendo o custo algorítmico e a latência de cauda e protegendo-se contra regressões, tudo no nível do código e do componente.
2.17 Concorrência e paralelismo: Escrever código concorrente correto adotando por padrão a imutabilidade e a troca de mensagens, entendendo condições de corrida, impasses e visibilidade de memória, escolhendo a sincronização e os modelos de mais alto nível adequados e testando deliberadamente o comportamento não determinístico.
2.18 Gestão de dependências e da cadeia de suprimentos: Gerenciar o código de terceiros que compõe a maior parte de um sistema moderno por meio de disciplina de versões e arquivos de bloqueio, uma cadência estável de atualização, uma pegada de dependências mínima e verificada e proveniência e uma lista de materiais de software para uma cadeia de suprimentos confiável.
2.19 Refatoração e dívida técnica: Melhorar o design interno de código que funciona atrás de uma suíte de testes confiável, reconhecendo code smells e aplicando pequenas refatorações nomeadas, usando a figueira-estranguladora para mudanças maiores e gerenciando a dívida técnica como um portfólio visível e financiado, e não como uma falha moral.
2.20 Tratamento de erros e padrões de resiliência: Decidir deliberadamente como o código falha e se recupera, por meio de contratos de erro claros, escolhas entre falhar rápido e falhar com segurança, novas tentativas com recuo e idempotência, disjuntores e degradação graciosa, e nunca engolir um erro em silêncio.
2.21 Sistemas de tipos e análise estática: Pegar classes inteiras de defeito antes de o código rodar, por meio de tipagem estática e gradual que torna os estados ilegais irrepresentáveis e de linters, verificadores de tipos e analisadores ligados ao editor e ao pipeline.
Como estes capítulos se relacionam
O fio condutor da Parte 2 é a capacidade de mudança em escala. Toda prática aqui existe para permitir que muitas pessoas alterem um sistema compartilhado e de longa vida com confiança. Os padrões de codificação (2.1) e os princípios de design (2.2) moldam o código para que você possa entendê-lo e modificá-lo. O design de interfaces (2.3) traça as fronteiras que permitem às equipes mudar seus internos de forma independente. O teste (2.4) fornece a rede de segurança que torna a mudança segura. A revisão de código (2.5) é onde o trabalho individual encontra a responsabilidade coletiva e onde os padrões são de fato impostos. O controle de versões (2.6) é a fundação sobre a qual a revisão, a integração e a auditoria repousam. E a documentação (2.7) preserva a intenção por trás de tudo isso para as pessoas que vêm depois.
Estes capítulos também alimentam o resto do guia. As interfaces e os princípios de design daqui se tornam os blocos de construção dos sistemas da Parte 3, especialmente os fundamentos de arquitetura (capítulo 3.1). A estratégia de testes (2.4) e o controle de versões (2.6) são a matéria-prima dos pipelines de entrega automatizados do capítulo 8.1. As práticas de documentação (2.7) se ligam diretamente aos runbooks e à observabilidade das operações, como no capítulo 9.2. E toda a parte se apoia nas fundações de valores e de tomada de decisão estabelecidas na Parte 1, transformando princípios compartilhados em ofício diário concreto.