O que é ser DRY?

Escrevi há algúns posts atrás sobre o que podemos aprender com a comunidade Ruby e Rails. Aqui vai outro conceito muito conhecido pela turma do Ruby e Rails, o DRY, ou Don’t Repeat Yourself (simplesmente, Não se Repita).

Isso não é somente um conceito de programação, mas sim uma filosofia que envolve não repetição, seja de código ou seja de idéias.

Esse conceito foi cunhado por Andrew Hunt and David Thomas no seu ótimo livro The Pragmatic Programmer. Lá eles dizem:

DRY—Don’t Repeat Yourself
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

O seu código reflete a forma de seu pensamento e conhecimento. Se você usa muitas repetições, isso significa que você não tem total conhecimento sobre o assunto, em outras palavras você está enrolando. Se não for isso é pior, você simplesmente está com preguiça de pensar melhor na solução.

Eu costumo citar o DRY para meus alunos quando estou falando de subrotinas e módulos de funções. Ou seja, ao invés de repetir a mesma rotina várias vezes no código, eu crio um FORM onde eu coloco a minha rotina e aí chamo essa rotina com o comando PERFORM quantas vezes eu precisar.

Esse recurso já é muito conhecido do mundo procedural e nada de novo tenho a dizer aos mais experiêntes em programação. Mas a grande novidade é que aprendi com o DRY que não é para repetir apenas código, mas idéias.

Minha Experiências

Estava trabalhando em um programa para batch input para condições de preço. O requisito era realmente muito simples, ler uma planiha Excel e abastecer as condições de preços via transação VK01. A transação VK01 é considerada um transação de fácil manipulação via batch input, então o programa seria realmente trivial.

Acontece que havia diversas tipos de condições o que necessitava de mapeamentos diferentes. O pior é que essas diversas condições não eram conhecidas chegavam em requisições diferentes. Mesmo assim, não importa o mapeamento, a tabela BDCDATA é mesma a ser preenchida e o comando para o CALL TRANSACTION é o mesmo. Opa, vamos fazer alguma coisa para não ficar repetindo código.

A primeira coisa que pensei foi fazer um FORM para encapsular as funções do batch input. Mas eu usária aquilo em vários programas. Então pensei em colocar essas rotinas em um include e chamar esse include de qualquer programa.

Problema resolvido! Tinha um código único que não seria repetido, pois estaria encapsulado em um include.

Temos DRY aqui? Não! Pelo menos não completo. Pois estava pensando em apenas não repetir o código, não estava pensando em não ficar repetindo as operações de batch input, ou seja, em todos os meus programas de batch input eu ainda repetia muita lógica.

Cuidado! É muito fácil repedir lógica. Repetição de lógica pode facilmente vir disfarçada de código diferente. Aí, se você está apenas pensando em DRY meia-boca, não perceberá a repetição de lógica.

Minha Solução DRY

Como eu apliquei DRY nesse caso? Eu encapsulei toda a lógica. Nesse caso eu criei um sistema de classes onde eu apenas eu teria que apenas que me importar em fazer o mapeamento.

Eu desenhei as classes de forma que eu poderia usar somente parte da lógica de batch input ou usá-la por completa.

Como eu usei classes, ficou muito fácil extender para usar em casos específicos. Considero umas das utilizações de classes mais legais que já fiz, pois isso me economizou muito trabalho posterior.

Nesse mesmo projeto, havia um gerador de código ABAP que não conseguia bater a minha produtividade quando eu usava as minhas classes. Fiquei realmente muito contente com os resultados.

DRY Completo

Isso é DRY, não se repita. Não repita código. Não repita lógica.

Experiemente DRY no seu dia-a-dia. Você conseguirá códigos mais elegantes e fáceis de fazer manutenção.