A veces, la duplicación de código es el resultado de un "juego de palabras": dos cosas se ven iguales, pero no lo son.
Es posible que el exceso de abstracción pueda romper la verdadera modularidad de su sistema. Bajo el régimen de modularidad, debe decidir "¿qué es probable que cambie?" y "¿qué es estable?". Lo que sea estable se coloca en la interfaz, mientras que lo que es inestable se encapsula en la implementación del módulo. Luego, cuando las cosas cambian, el cambio que necesita hacer está aislado en ese módulo.
La refactorización es necesaria cuando lo que creía que era estable (por ejemplo, esta llamada a la API siempre tomará dos argumentos) debe cambiar.
Entonces, para estos dos fragmentos de código duplicados, preguntaría: ¿un cambio requerido en uno necesariamente significa que el otro también debe cambiarse?
La forma en que respondas esa pregunta podría darte una mejor idea de lo que podría ser una buena abstracción.
Los patrones de diseño también son herramientas útiles. Quizás su código duplicado esté atravesando alguna forma, y el patrón iterador debería aplicarse.
Si su código duplicado tiene múltiples valores de retorno (y es por eso que no puede hacer un método de extracción simple), entonces quizás debería hacer una clase que contenga los valores devueltos. La clase podría llamar a un método abstracto para cada punto que varía entre los dos fragmentos de código. Luego haría dos implementaciones concretas de la clase: una para cada fragmento. [Este es efectivamente el patrón de diseño del Método de plantilla, que no debe confundirse con el concepto de plantillas en C ++. Alternativamente, lo que está viendo podría resolverse mejor con el patrón Estrategia.]
Otra forma natural y útil de pensarlo es con funciones de orden superior. Por ejemplo, hacer lambdas o usar clases internas anónimas para que el código pase a la abstracción. En general, puede eliminar la duplicación, pero a menos que realmente haya una relación entre ellos [si uno cambia, también lo debe hacer el otro], entonces podría estar dañando la modularidad, no evitándola.
Personalmente lo ignoro y sigo adelante. Lo más probable es que si es un caso extraño, es mejor duplicarlo, ¡podría pasar años refactorizando y el próximo desarrollador echará un vistazo y deshacerá su cambio!
fuente
Sin una muestra de código, es difícil decir por qué su código no tiene una abstracción fácilmente identificable. Con esa advertencia, aquí hay un par de ideas:
La mayor dificultad en este ejercicio es que su función probablemente incorpore demasiados comportamientos no relacionados en un nivel de abstracción dado, y necesita manejar algunos de ellos en niveles inferiores. Usted supone correctamente que la claridad es clave para mantener el código, pero aclarar el comportamiento del código (su condición actual) es muy diferente de aclarar la intención del código.
Haga que el resumen de las piezas de código más pequeñas haga que sus firmas de función identifiquen el qué, y las piezas más grandes deberían ser más fáciles de clasificar.
fuente