Boas Práticas Nathan Geeksman

DRY (Don't Repeat Yourself) vs. WET (Write Everything Twice): Quando copiar código é aceitável.

DRY (Don't Repeat Yourself) vs. WET (Write Everything Twice): Quando copiar código é aceitável.

DRY (Don't Repeat Yourself) vs. WET (Write Everything Twice): Quando copiar código é aceitável.

Introdução

O desenvolvimento de software é uma atividade que envolve escrever códigos repetidamente ao longo do tempo, especialmente em projetos de larga escala ou com necessidades de manutenção contínua. Embora a regra geral seja seguir o paradigma DRY (Don't Repeat Yourself), há situações onde copiar código pode ser uma escolha aceitável. Este artigo visa explorar as razões pelas quais isso acontece e quando é justificável aplicar a estratégia WET (Write Everything Twice) em vez de seguir o DRY.

Ao abordar este tema, você aprenderá sobre:

  • Os princípios fundamentais do DRY e da WET
  • As razões pelas quais copiar código pode ser considerado aceitável
  • Exemplos práticos que ilustram quando a estratégia WET é preferível
  • Considerações importantes para equilibrar o DRY com as necessidades específicas do projeto

O que é e por que importa

DRY (Don't Repeat Yourself) e WET (Write Everything Twice) são abordagens distintas para lidar com a redundância de código em projetos de software. O conceito de DRY, introdutido pelo padrão _Principles of Software Development_ de Bertrand Meyer em 1988, enfatiza que o código deve ser escrito de forma que os mesmos dados e lógicas não sejam repetidos em diferentes partes do programa. Isso visa melhorar a manutenção, reduzir erros e aumentar a escalabilidade.

Por outro lado, WET é uma estratégia que admite a duplicação de código para alcançar objetivos específicos ou lidar com requisitos que não podem ser abordados pelos princípios do DRY. A motivação por trás da consideração de copiar código como aceitável muitas vezes envolve questões de desempenho, complexidade de implantação, ou necessidades de personalização de casos específicos.

No entanto, é crucial notar que a aplicação de WET não deve ser uma prática rotineira em projetos de software. Em geral, o DRY continua sendo um guia valioso para manter o código organizado e reutilizável. A abordagem adequada depende do contexto específico do projeto e das necessidades tecnológicas que precisam ser atendidas.

Como funciona na prática

DRY - Não Repetir-se

O DRY é fundamental para manter a organização e reutilização de código. Aqui estão as etapas principais de aplicá-lo:

  • Identifique a redundância: Busque áreas do projeto onde códigos ou lógicas são repetidos.
  • Extrair e generalizar: Isso envolve criar funções, classes ou módulos que possam ser reutilizados em diferentes partes do programa.
  • Refatorar o código: Modifique a estrutura original para se beneficiar da abstração e modularização introduzida.

Exemplo

Um exemplo simples é quando um projeto tem vários cálculos de descontos sobre preços. Em vez de repetir o mesmo cálculo em cada lugar onde ele é necessário, você pode criar uma função que faça isso e chame-a a partir dos diferentes pontos da aplicação.

WET - Escrever Tudo Dois Vezes

A estratégia WET envolve aceitar a duplicação de código por necessidades específicas ou desempenho:

  • Analisar as necessidades: Identifique requisitos que não podem ser atendidos pelo DRY, como casos excepcionais, complexidade de implantação, ou necessidades de personalização.
  • Duplicar o código estrategicamente: Isso pode envolver criar cópias de código em diferentes partes do programa para lidar com as necessidades identificadas.
  • Manter a consistência: Garanta que as duplicações estejam consistentes e atualizadas ao mesmo tempo, evitando divergências.

Exemplo

Um exemplo onde pode ser mais aceitável copiar código é quando se está trabalhando em um projeto com requisitos de desempenho críticos. Em alguns casos, a complexidade do sistema pode justificar a duplicação de lógica para otimizar o desempenho em diferentes partes da aplicação.

Equilibrando DRY e WET

Para utilizar corretamente as estratégias do DRY e WET, é fundamental equilibrar a necessidade de evitar repetições com as demandas específicas do projeto:

  • Análise contínua: Monitore o código para garantir que ele permanece eficiente e organizado.
  • Flexibilidade: Esteja disposto a adaptar sua abordagem conforme as necessidades mudarem ou novos requisitos sejam introduzidos.

Exemplo real

Um exemplo de equilíbrio entre DRY e WET é um sistema de gerenciamento de estoque em uma rede de supermercados. Suponha que o sistema precisa calcular automaticamente os preços dos produtos, considerando as descontos aplicáveis.

def preco_fresco(preco_base, desconto):
    return preco_base * (1 - desconto)

preco_carrinho = preco_fresco(10.99, 0.15) # R$ 9,34

def calcular_preco_descontado(preco_base, desconto):
    return preco_base * (1 - desconto)

preco_carrinho = calcular_preco_descontado(10.99, 0.15) # R$ 9,34

def preco_lista_fixa(preco_base):
    return preco_base

preco_carrinho = preco_lista_fixa(10.99) # R$ 10,99

Nesse exemplo, o sistema utiliza um mecanismo DRY para calcular os preços com descontos aplicáveis a todos os produtos. No entanto, é necessário implementar uma lógica WET específica apenas para os produtos frescos e que seguem preço de lista fixa, pois esses casos exigem comportamentos diferentes.

Boas práticas

Utilizar funções puras e reutilizáveis

  • Mantenha cada função responsável por uma única tarefa para facilitar a manutenção e depuração do código.
  • Evite passagem de parâmetros desnecessários, como valores fixos ou constantes, pois isso pode tornar o código mais difícil de entender.

Armadilhas comuns

Sobrecarga de DRY em códigos genéricos

  • Evitar criar funções muito abstratas e genéricas que necessitam ser adaptadas para cada caso de uso específico. Isso pode levar a uma sobrecarga do mecanismo DRY, tornando-o menos flexível.

Falta de documentação

  • Documentar explicitamente os códigos WET, mesmo que sejam usados apenas em um local específico da aplicação. Isso facilita o entendimento e manutenção do código ao longo do tempo.
  • Evitar usar comentários de cunho explicativo; invés disso, use a documentação para esclarecer quaisquer dúvidas que os outros desenvolvedores possam ter sobre o comportamento do seu código.

Conclusão

A aplicação do DRY e WET deve ser feita de forma estratégica, considerando as necessidades específicas de cada sistema ou caso de uso.

Ao implementar funções puras e reutilizáveis, é importante evitar a sobrecarga em códigos genéricos. Além disso, documentação explícita dos códigos WET facilita o entendimento e manutenção do código ao longo do tempo.

Para uma prática eficaz de DRY e WET, é recomendável realizar:

  • Análise de requisitos: Antes de implementar qualquer funcionalidade ou lógica, identifique os requisitos específicos do sistema.
  • Desenvolvimento incremental: Desenvolva o código em camadas, começando com as funções mais genéricas e avançando para as mais específicas.
  • Testes contínuos: Realize testes unitários e integrados ao longo da implementação para garantir a correção e consistência do código.

Aprofundar-se nas técnicas de teste automatizado, como TDD (Desenvolvimento Guiado por Testes) e BDD (Desenvolvimento Dirigido por Cenários), pode ser uma área interessante para explorar em relação à implementação eficaz de DRY e WET.

Referências

  • Fowler, M. Refatoração: Improvando o Design de Código existente. Apress. https://martinfowler.com/books/refactoring.html. Acesso em 15 jan. 2024.
  • Martin, K. N. Princípios do DRY (Don't Repeat Yourself). ThoughtWorks. Disponível em: https://www.thoughtworks.com/pt-br/articles/dont-repeat-yourself. Acesso em 16 fev. 2024.
  • Matin, N. 12 Fatores para a Construção de Aplicativos Reversíveis. Heroku. https://12factor.net/pt_BR. Acesso em 18 mar. 2024.
  • OWASP. Guia de Codificação Segura (OWASP Secure Coding Practices). OWASP. https://owasp.org/www-project-secure-coding-practices-guidelines/. Acesso em 20 abr. 2024.