Como remover o código duplicado (em geral)?

10

Em uma linguagem OO (por exemplo, mas não se limitando a Java), como você corrige código duplicado, dependendo do escopo de sua ocorrência? Eu começaria com (por exemplo)

  • na mesma classe (escopo), execute a refatoração do método Extract (correção)
  • nas classes da mesma hierarquia (escopo), execute Extract Method e Pull Up (fix)
  • ...
Peter Kofler
fonte
veja um exemplo para implementar o princípio DRY (não se repita) com a mesma classe: geekswithblogs.net/chrisfalter/archive/2008/03/07/…
NoChance
A pergunta original no SO ( stackoverflow.com/questions/7380946/… ) foi encerrada. Então eu mudei para cá.
Peter Kofler 12/09

Respostas:

8

Recentemente, encontrei uma boa resposta para minha pergunta no "Código Limpo" do tio Bob, que quero compartilhar. Ele diferencia três tipos de duplicação

Pedaços de código idêntico devem ser substituídos por um único método. Portanto, a correção seria extrair o método e delegar ao comportamento comum.

  • no mesmo método, execute Extrair variável local e reutilize-a.
  • na mesma classe, execute a refatoração de Método de Extração.
  • nas classes da mesma hierarquia Extrair Método e Subir. Uma hierarquia pode ser criada para encontrar um local para os métodos.
  • nas classes de hierarquias separadas, use delegação para novos objetos.
  • Se os métodos não precisarem de nenhum estado envolvente, o padrão "lib" poderá ser aplicado (que é um contêiner para métodos estáticos, geralmente chamado SthUtilou SthLib).

casos de switch/casee if/elseque sempre testam o mesmo conjunto de condições .

  • Estes devem ser substituídos por polimorfismo.

Módulos que implementam algoritmos semelhantes . Eles são mais difíceis de encontrar, pois nenhum detector de clone pode encontrá-los.

  • Como o escopo é maior, são utilizados padrões de design. O padrão de design do método de modelo pode ser aplicado a algoritmos dentro de uma hierarquia de classes.
  • O padrão de design da estratégia pode ser aplicado a qualquer algoritmo usado em lugares diferentes.

Também é um ponto válido mencionado por Oded, ao lidar com diferentes versões de bibliotecas

  • consolidar em uma única versão. O padrão de design da fachada pode ajudar aqui.

No final, a melhor frase para responder à minha pergunta é por estímulos:

O método de reutilização de código usado nos idiomas OO é um objeto.

Peter Kofler
fonte
5

Em geral - consolide o código duplicado em um único local e verifique se o site de duplicação original está chamando o local consolidado.

Nos seus exemplos, dentro de uma classe, esse seria o método extraído e, dentro de um conjunto de classes, o método pull-up dentro da classe base.

No código copiar e colar, isso seria remover as duplicatas e garantir que qualquer usuário agora use a cópia única (em qualquer nível que seja).

Ao lidar com diferentes versões de bibliotecas, consolide em uma única versão (se possível).

Oded
fonte
Não seria o método "pull-down" se estivesse em uma classe base? Eu sempre imagino classes base como fisicamente sob as classes derivadas.
Dave Nay
O nome próprio do livro Refatoração é "pull up".
Peter Kofler
1

Eu acho que essa é uma pergunta em aberto, mas também depende do estado do código. Quero dizer, você pode tolerar o código duplicado um pouco, dependendo do contexto. A regra dos três é boa para esse assunto.

Regra de três Na primeira vez que você faz algo, você apenas faz. Na segunda vez que você faz algo semelhante, estremece com a duplicação, mas faz a coisa duplicada de qualquer maneira. Na terceira vez que você faz algo semelhante, refatora.

Embora isso seja bastante discutível, este post também considera casos em que você toleraria código duplicado.

Will Hughes
fonte
11
+1 sobre a "regra dos três". Fico sempre espantado com o quão amplamente aplicável é.
andy manga
11
Isso não responde à pergunta de como .
precisa