Código DRY não relacionado, mas quase idêntico

34

Eu tenho algum código que é quase idêntico, mas usa tipos absolutamente diferentes, sem herança entre eles, na variável principal. Especificamente, estou escrevendo um analisador com Roslyn para C # e VB.NET, com os seguintes tipos:

Microsoft.CodeAnalysis.CSharp.Syntax.AttributeSyntax Microsoft.CodeAnalysis.VisualBasic.Syntax.AttributeSyntax

Gostaria de saber se, como o código está fazendo a mesma coisa, devo mantê-lo o mais SECO possível, dividindo o mínimo possível em métodos separados (mas idênticos, exceto o tipo), ou separá-lo completamente porque os dois métodos são mudanças não relacionadas e futuras podem forçar uma versão a mudar, mas não a outra (embora isso seja improvável)?

Edit: Um ano depois, eu encontrei o mesmo problema, e a equipe de Roslyn me ajudou a resolvê-lo: escreva uma classe base que use genéricos e tenha um TAttributeSyntaxparâmetro que faça a maior parte do trabalho. Em seguida, escreva classes derivadas com o mínimo de dados necessários para um tipo específico.

Hosch250
fonte
Funcionaria para criar sua própria interface AttributeSyntax que agrupa as classes existentes, mas fornece a herança que conceitualmente deveria estar lá?
Winston Ewert
7
Desculpe se isso é óbvio, mas existem genéricos para que você não precise se repetir para um código idêntico, mas para o tipo. Se não foi isso que você quis dizer, desconsidere.
Davislor
@Lorehead Normalmente, eu faria isso, mas esse é um método único que está sendo transmitido por um tipo que contém o nó como uma carga útil de um método interno sobre o qual não tenho controle.
Hosch250
@WinstonEwert Vou analisar isso. Não tenho certeza se quero fazer isso para todos os tipos de C # / VB.NET.
Hosch250
11
A refatoração impõe muitos compromissos e, às vezes, até paradoxos. Por exemplo, acoplamento solto incorreto vs. DRY, ou funções curtas, mas muitas delas, vs. funções mais longas e poucas delas. No final, é uma fera difícil: seu objetivo é a legibilidade e a manutenção. Você precisa pensar como um avatar que vê seu código pela primeira vez. E às vezes você apenas tenta ver o que é melhor. Infelizmente, a refatoração perfeita não é possível.
Phresnel

Respostas:

111

Você não faz DRY porque alguém escreveu em um livro em algum lugar que é bom fazer, você faz DRY porque na verdade tem benefícios tangíveis.

Especificamente dessa pergunta:

Se você se repetir, poderá criar problemas de manutenção. Se todos os doStuff1-3 tiverem código estruturado da mesma forma e você resolver um problema em um, você poderá facilmente esquecer de corrigi-lo em outros lugares. Além disso, se você precisar adicionar um novo caso para lidar, basta passar parâmetros diferentes para uma função em vez de copiar e colar em todo o lugar.

No entanto, o DRY é frequentemente levado ao extremo por programadores inteligentes. Às vezes, para não se repetir, é necessário criar abstrações tão obtusas que seus colegas de equipe não possam segui-las. Às vezes, a estrutura de duas coisas é apenas vagamente semelhante, mas diferente o suficiente. Se o doStuff1-4 for diferente o suficiente, de modo que refatorá-los para não se repetir faz com que você precise escrever um código não natural ou sofrer backflips de codificação inteligentes que farão com que sua equipe o ofenda, então pode ser bom repetir-se. Eu me inclinei para trás para não me repetir algumas vezes de maneiras não naturais e me arrependi do produto final.

Então, basicamente, não pense "oh cara, esse código é bem parecido, talvez eu deva refatorar para não me repetir". Pense "a refatoração para fazer com que essa base de código reutilize elementos comuns torna o código mais sustentável ou menos sustentável ?" Em seguida, escolha o que o torna mais sustentável.


Dito isto, considerando o SRP e apenas tentando ter classes pequenas e flexíveis em geral, pode fazer sentido analisar seu código por esse motivo , separar partes do comportamento que usam tipos genéricos (você disse que eles são idênticos, exceto o tipo) em turmas pequenas. Depois, você descobrirá que algumas dessas classes são totalmente idênticas (não apenas idênticas) e, em seguida, poderá criar um kit de ferramentas, caso deseje adicionar Microsoft.CodeAnalysis.CPlusPlus.Syntax.AttributeSyntax.

durron597
fonte
32
TL; DR - DRY é um meio para atingir um fim. Concentre-se no fim, não nos meios. Se eu pudesse votar duas vezes no Lego Man, eu o faria.
Uma nota importante: se você faz repetir-se, sempre mencionar no comentário todos os outros lugares que devem ser visitados Quando as alterações de código repetidos. Não apenas reduz a probabilidade de uma dessincronização, mas também funciona como um indicador de quanta dor de manutenção a repetição está causando a você.
Xion