Código SECO no relacionado, pero casi idéntico

34

Tengo un código que es casi idéntico, pero usa tipos absolutamente diferentes, sin herencia entre ellos, en la variable principal. Específicamente, estoy escribiendo un analizador con Roslyn para C # y VB.NET, con los siguientes tipos:

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

Me pregunto si, debido a que el código está haciendo lo mismo, debería mantenerlo lo más SECO posible, dividiéndolo lo menos posible en métodos separados (pero idénticos aparte del tipo), o separarlo completamente porque los dos métodos son cambios no relacionados y futuros podrían obligar a una versión a cambiar, pero no a la otra (aunque esto es poco probable)?

Editar: Un año más tarde, llegué a este mismo problema, y ​​el equipo de Roslyn me ayudó a resolverlo: escriba una clase base que tome genéricos y tenga un TAttributeSyntaxparámetro que haga la mayor parte del trabajo. Luego, escriba las clases derivadas con el mínimo de datos que necesita un tipo específico.

Hosch250
fuente
¿Funcionaría crear su propia interfaz AttributeSyntax que envuelva las clases existentes pero le dé la herencia que conceptualmente debería estar allí?
Winston Ewert
77
Lo siento si esto es obvio, pero existen genéricos para que no tenga que repetir el código idéntico sino el tipo. Si eso no es lo que quiso decir, por favor no lo tenga en cuenta.
Davislor
@Lorehead Normalmente haría eso, pero este es un método único al que se le pasa un tipo que contiene el nodo como carga de un método interno sobre el que no tengo control.
Hosch250
@ WinstonEwert Lo investigaré. Sin embargo, no estoy seguro de querer hacer eso para todos los tipos de C # / VB.NET.
Hosch250
1
La refactorización impone muchos compromisos y, a veces, incluso paradojas. Por ejemplo, wrt acoplamiento flojo vs. DRY, o funciones cortas, pero muchas de ellas, vs. funciones más largas, y pocas de ellas. Al final, es una bestia difícil: su objetivo es la legibilidad y la facilidad de mantenimiento. Debes pensar como un avatar que ve tu código por primera vez. Y a veces solo intentas ver qué es mejor. La refactorización perfecta lamentablemente no es posible.
phresnel

Respuestas:

111

No haces DRY porque alguien lo escribió en un libro en algún lugar que es bueno hacer, lo haces DRY porque en realidad tiene beneficios tangibles.

Específicamente de esa pregunta:

Si se repite, puede crear problemas de mantenimiento. Si doStuff1-3 tiene un código estructurado de manera similar y soluciona un problema en uno, podría olvidarse fácilmente de solucionar el problema en otros lugares. Además, si tiene que agregar un nuevo caso para manejar, simplemente puede pasar diferentes parámetros a una función en lugar de copiar y pegar en todo el lugar.

Sin embargo, DRY a menudo es llevado al extremo por programadores inteligentes. A veces, para no repetirse, debe crear abstracciones tan obtusas que sus compañeros de equipo no puedan seguirlas. A veces, la estructura de dos cosas es solo vagamente similar pero lo suficientemente diferente. Si doStuff1-4 es lo suficientemente diferente como para que refactorizarlos para que no se repitan, tendrá que escribir un código no natural o someterse a un retroceso de codificación inteligente que hará que su equipo lo fulmine con la mirada, entonces puede estar bien repetirlo. Me he esforzado por no repetirme un par de veces de forma antinatural y lamenté el producto final.

Entonces, básicamente, no pienses "oh hombre, este código es bastante similar, tal vez debería refactorizar para no repetirme". Piense "¿la refactorización para hacer que esta base de código reutilice elementos comunes hace que el código sea más fácil de mantener o menos mantenible ?" Luego, elija el que lo haga más fácil de mantener.


Dicho esto, dado el SRP y solo tratar de tener clases pequeñas y flexibles en general, podría tener sentido analizar su código por esa razón , separar partes de comportamiento que usan tipos genéricos (usted dijo que son idénticos aparte del tipo) en Clases pequeñas. Luego descubrirá que algunas de estas clases en realidad son totalmente idénticas (no solo casi idénticas), y luego puede crear un kit de herramientas en caso de que desee agregar Microsoft.CodeAnalysis.CPlusPlus.Syntax.AttributeSyntax.

durron597
fuente
32
TL; DR - DRY es un medio para un fin. Concéntrese en el fin, no en los medios. Si pudiera votar dos veces al Lego Man, lo haría.
Una nota importante: si lo hace repetir a sí mismo, siempre se menciona en el comentario de todos los otros lugares que deben ser visitados cuando cambia el código repetidos. No solo reduce la probabilidad de una desincronización, sino que también funciona como un indicador de cuánto dolor de mantenimiento le está causando la repetición.
Xion