4 pontos por GN⁺ 2024-10-30 | 1 comentários | Compartilhar no WhatsApp

Escrevendo código que seja fácil de apagar

  • Toda linha de código traz um custo de manutenção. Reutilizar código torna mudanças mais difíceis.
  • Quanto mais consumidores uma API tiver, mais código precisará ser reescrito ao alterá-la.
  • Gerenciar as dependências do código é um problema importante em sistemas de grande escala.

Etapa 0: não escrever código

  • O número de linhas de código, por si só, não fornece muita informação.
  • O código que não foi escrito é o mais fácil de apagar.

Etapa 1: copiar e colar código

  • Código reutilizável pode ser escrito mais facilmente depois, com base em exemplos.
  • Copiar e colar código é uma forma de evitar dependências e ganhar flexibilidade.

Etapa 2: não copiar e colar código

  • Se o código já foi copiado e colado o suficiente, é hora de extraí-lo para uma função.
  • Pode ser uma boa ideia criar um diretório util para guardar vários utilitários em outros arquivos.

Etapa 3: escrever mais boilerplate

  • Boilerplate é parecido com copiar e colar código, mas altera o código em lugares diferentes.
  • Boilerplate reduz dependências e oferece flexibilidade.

Etapa 4: não escrever boilerplate

  • Se houver boilerplate demais, ele deve ser encapsulado por uma biblioteca com opiniões sobre política, fluxo de trabalho e estado.
  • A relação entre requests e urllib3 é um bom exemplo.

Etapa 5: escrever grandes blocos de código

  • A lógica de negócio é marcada por casos de exceção sem fim e hacks rápidos e sujos.
  • É mais fácil apagar um erro grande do que apagar vários erros pequenos.

Etapa 6: dividir o código em partes

  • Grandes blocos de código têm alto custo de manutenção.
  • É preciso separar as responsabilidades do código e projetar módulos levando em conta a possibilidade de mudanças.

Etapa 7: continuar escrevendo código

  • Deve ser possível escrever código novo de forma independente do código existente, para experimentar novas ideias.
  • Feature flags são uma forma de poder mudar de ideia depois.

Resumo do GN⁺

  • Este texto explica como escrever código que seja fácil de apagar.
  • O ponto principal é reduzir as dependências do código, aumentar a flexibilidade e diminuir o custo de manutenção.
  • requests e urllib3 são projetos com funções semelhantes mencionados no texto.
  • Este texto relembra desenvolvedores de software da importância da gestão e da manutenção de código.

1 comentários

 
GN⁺ 2024-10-30
Comentários do Hacker News
  • Gosto da frase "Simple is robust". Significa que, quanto menor a complexidade do sistema, mais fácil é mudá-lo. O planejamento para o futuro deve ser feito com código intuitivo, e não com código escalável. Por exemplo, abstrair só quando a situação exigir, incentivar duplicação simples, usar um monólito no início e priorizar escala vertical em vez de horizontal. Ao construir vários sistemas 0-1, encontrei esses pontos em comum.

  • Surpreende não haver menção a testes ou observabilidade. Testes têm custo de manutenção, mas reduzem o risco de problemas ao remover código. Ao expor um serviço para chamadores externos, é preciso um método forte para marcar algumas chamadas como obsoletas e observar se ainda estão sendo usadas. Recentemente removi resolvers de GraphQL de forma semiautomática e usei métricas de frequência de uso para identificar quais resolvers não podiam ser deletados. O GraphQL tem anotações de depreciação, mas no serviço isso não era tratado de forma especial. Adicionando observabilidade para marcar quando uma função obsoleta foi chamada, e depois de rodar isso em produção por tempo suficiente, é possível remover com segurança código exposto externamente.

  • Acabei promovendo a ideia de "projetar para apagar". No passado, eu achava que dava para planejar todas as situações e criar uma obra que atendesse a todas as necessidades, mas é difícil prever as necessidades futuras. Um dia, aquilo que eu fiz vai se tornar inútil para alguém, e será justificável que essa pessoa o desmonte. Portanto, é preciso se esforçar para tornar a remoção fácil. Isso muitas vezes resulta em menos acoplamento, mas é diferente do impulso de desenvolvedores jovens de separar tudo em frameworks meta-configuráveis. Às vezes, um acoplamento forte é melhor quando é mais fácil de entender logicamente.

  • Para escrever código fácil de apagar, é preciso repetir para evitar dependências, e não repetir para gerenciar. É preciso dividir o código em camadas e construir APIs simples sobre partes que podem ser simples de implementar, mas incômodas de usar. É preciso separar o código e isolar tanto as partes difíceis de escrever quanto as partes com maior chance de mudar do restante do código e umas das outras. Nem todas as escolhas devem ficar hardcoded; algumas devem poder ser alteradas em runtime. Pela minha experiência, código fácil de apagar é em camadas e modularizado, então também é fácil de expandir.

  • Eu costumava dizer aos estudantes de física computacional que o melhor cálculo é aquele com o qual você não precisa se preocupar.

  • Pessoalmente, separo o código em lógica de negócio e implementação real. A lógica de negócio pode ser duplicada por sua própria natureza, mas detalhes técnicos demais não deveriam ser duplicados. Desde que a lógica de negócio não lide diretamente com a aplicação e permaneça independente dela, ela pode ser tão bagunçada quanto você quiser. Se surgir um problema e aquilo não funcionar bem, existe a opção de apagar a implementação inteira, corrigi-la e não ser forçado a procurar a especificação real dentro da implementação.

  • O erro óbvio do primeiro parágrafo: o problema do reúso de código seria atrapalhar você a mudar de ideia depois. Isso geralmente é uma afirmação errada. Se você mudar de ideia e o código tiver sido copiado e colado em dez lugares, terá de mudar os dez lugares. Se, por outro lado, o código estiver em uma função, você muda uma vez só. Se uma das dez chamadas não deve ser alterada, ainda assim você pode copiar e colar, e também pode tornar a função mais genérica. Assim como não olhar para os lados ao atravessar a rua, copiar e colar quase sempre é uma má ideia.

  • Há uma excelente correlação: código ruim permanece por muito tempo porque é difícil removê-lo.

  • Fico me perguntando se isso quer dizer que devemos usar software o mais próximo possível do estado padrão e evitar customizações profundas.