smells smell lazy guru feature envy data code bad refactoring code-duplication

refactoring - lazy - feature envy code smell



¿Cuán fanáticamente eliminas la Duplicación de código? (17)

¿Qué tan fanático eres acerca de la eliminación del código duplicado?

Personalmente, cada vez que veo código duplicado, ya sea en el código de prueba o en la producción, tiendo a refactorizar la duplicación. La única excepción que hago son estos:

  1. A veces, la reducción en la duplicación es muy mínima, porque el método recientemente refactorizado tiene demasiados parámetros para ser realmente útil / legible.
  2. Algunas veces, en el código de prueba, cuando varias pruebas usan la misma pieza de código que no es realmente un flujo coherente, dejo la duplicación sola (pero no siempre, dependiendo del tamaño del duplicado).

Lo considero el indicador individual más importante de un buen programador. Si puedes escribir un código con todos los factores, entonces casi por definición es un buen código.

Parece que casi todas las demás prácticas de programación son solo formas de obtener tu código SECO.

Esto es un poco exagerado, pero no demasiado. Entre estar DRY y hacer que tus interfaces sean lo más estables y mínimas posible (Separation of Concerns), estás en camino de convertirte en un verdadero ingeniero de software y no en un programador / pirata informático.


MUY. En lo que a mí respecta, casi todos nuestros consejos de desarrollo, refranes y "mejores prácticas" derivan del principio de no repetir el código y hacerlo reutilizable. MVC, decorador, OOP, etc.

Obviamente uno necesita mantener un sentido de pragmatismo a veces, pero tiendo a inclinarme mucho hacia DRY.


Como se ha dicho, trato de vivir según el principio "DRY", pero también diría que hay otra condición en la que a menudo soy reacio a eliminar la duplicación:

  • No modifique el código para el cual no tiene (o no puede desarrollar económica / prácticamente) una prueba de unidad.

Ese conjunto de pruebas incluiría el código de llamada para cualquier método extraído.

Si no puedo probarlo, no puedo decir que no he introducido un defecto. Con un banco de pruebas, al menos puedo decir que hizo lo que solía hacer.


Dado que la duplicación se presta a copiar y pegar, siempre trato de evitar la duplicación o refactorización cuando ya existe una duplicación en el código existente.


Evite factorizar el código donde los parámetros de configuración (necesarios para alterar el comportamiento) obscurecen la intención del código. Ve lo más lejos que puedas antes de llegar a este punto ... pero es un acto de equilibrio.


Me considero un fanático extremo cuando se trata de eliminar la duplicación de código. Mientras no estemos en un punto crítico en un hito, hago mi mejor esfuerzo para eliminar cualquier código duplicado que encuentre en mi código. Finalmente, simplemente me quedo sin tiempo y tengo que dejar el código solo para el próximo hito. Sin embargo, en ese caso, a menudo consulto al menos un comentario que indica la duplicación y lo que se debe hacer para eliminarlo.


Normalice el código, normalice las variables, normalice la base de datos, normalice la jerarquía corporativa, normalice el gobierno ...


Para empezar, era bastante fanático, pero una experiencia reciente probablemente me ha hecho más, y me ha dado otro conjunto de herramientas para usar. Específicamente, algoritmos / conceptos de bioinformática. En una posición nueva, estamos actualizando la IU web para usar el diseño dirigido por CSS en lugar de las tablas, por lo que estoy analizando 700 archivos JSP existentes. Puse todas las líneas de código en una base de datos y de 100K líneas totales, menos de 20K eran únicas. Luego represento cada archivo como una secuencia de identificadores de línea, y encuentro las subsecuencias comunes de 2 o más líneas; el más largo tenía casi 300 líneas duplicadas entre un par de archivos JSP, y un caso atroz de corte y pasado. Ahí es donde me encuentro ahora, pero mi próximo plan es volver a representar los archivos como una secuencia de line_id OR (común) subsequence_id''s, ordenarlos y luego realizar una comparación de Levenshtein de archivos contiguos entre sí dentro del orden de clasificación. Esto debería ayudar en la correspondencia difusa de archivos que no solo contienen subsecuencias comunes, sino subsecuencias que están desactivadas por uno y tal.


Siempre trato de pensar primero por qué este código está duplicado. La mayoría de las veces, la respuesta es pereza / ignorancia / etc., y yo refactorio. Pero, de vez en cuando, aparece el caso donde la duplicación es realmente válida. De lo que estoy hablando aquí es de dos piezas de código semánticamente no relacionadas, pero que tienen la misma implementación (o similar) en este momento . Considere, por ejemplo, reglas comerciales para procesos (reales) completamente no relacionados. Las reglas pueden ser iguales un día, y al día siguiente uno de ellos cambia. Es mejor esperar que no estén representados por el mismo código, o rezar para que el desarrollador que realiza la modificación pueda detectar lo que está sucediendo (pruebas unitarias, ¿alguien?).


Solía ​​ser bastante laissez faire al respecto, obviamente, trato de evitar la duplicación siempre que sea posible, pero si necesita copiar las 15 líneas de código ocasionales de aquí para allá para guardar la refacturación de una tarde, eso probablemente sea correcto siempre y cuando lo haga. no hagas un hábito de eso.

Entonces comencé mi trabajo actual.

El tipo que escribió la mayor parte de esta base de código antes que yo tomó la línea de "optimización prematura es la raíz de todo mal" y es ridículamente extrema. Ejemplo: hubo al menos cinco lugares diferentes en la aplicación que calcularon el tamaño de una miniatura de un gráfico cargado. Parecía el tipo de cosa que podía racionalizar, hasta que me di cuenta de que las miniaturas de los 5 "caminos" se mostraban en la misma pantalla, y cada función hacía las matemáticas de una manera ligeramente diferente y obtenía resultados ligeramente diferentes. Todos habían comenzado como pastas de copia, pero cada uno había sido utilizado en caliente durante más o menos un año hasta que llegamos a donde lo encontré.

Entonces, TODO eso fue refactorizado. Y ahora soy un fanático de la extracción de engaños.


Soy bastante psicópata al respecto. Si hago algo más de una vez, refactorizo. Punto. Signo de exclamación.


Soy un gran creyente en la codificación DRY. No te repitas. Si lo haces más de una vez, ponlo en una clase de ayuda.

Hay muy poco que sea peor que tener que recordar hacer cambios a la misma cosa en varios lugares.


Siempre me he adherido al principio de que la primera duplicación (es decir, original más una copia) no suele valer la pena el esfuerzo de eliminarla. Esto se debe a que el original más una copia es probablemente un "único", y no obtiene lo suficiente de eliminarlos para justificar el trabajo.

Sin embargo, tan pronto como comienzo a hacer una segunda copia, reescribo las tres para eliminar la duplicación. Eso es porque ahora (en mi opinión) se ha movido de "una sola vez" a "tendencia". Es más probable que vuelva a utilizar el código, por lo que vale la pena el esfuerzo por eliminar los duplicados.

Dudo en llamar al proceso "refactorización", porque esa es una palabra de moda del campo de XP, y lo hice a principios de los 80 con FORTRAN y C.

Una buena práctica de programación no tiene edad (y, por lo general, tampoco está de moda).

Aclamaciones,

-Ricardo


Trabajamos en eso Realmente ayuda tener una herramienta que detecta dicha duplicación; independientemente de las mejores intenciones, sucede porque uno no piensa, o hay un horario apretado, etc.

El CloneDR encuentra código duplicado, copias exactas y casi errores, en sistemas fuente de gran tamaño, parametrizados por sintaxis de lenguaje. Es compatible con Java, C #, COBOL, C ++, PHP y muchos otros idiomas. Lo usamos nosotros mismos para ayudar a administrar nuestro propio código.


La duplicación de código puede morder rápidamente en la espalda y causarle mucho dolor. Si veo un código duplicado (generalmente código antiguo de otras personas, por supuesto;)) Intento refactorizarlo de inmediato. Es muy raro que no valga la pena el esfuerzo. Pase el tiempo ahora o pasará más tiempo haciéndolo más tarde.


A veces soy culpable de copiar y pegar, pero trato de eliminar la duplicación siempre que sea posible. La excepción es cuando tengo una función que llama a otras funciones y es muy lenta. A veces, el contenido de las subfunciones se puede combinar para la velocidad, o las consultas SQL subyacentes se pueden combinar en menos o solo una.

Ejemplo: en la gestión de inventario, la cantidad mínima disponible para un artículo es igual a la cantidad en su reserva de trabajo más la cantidad en stock de seguridad. Las existencias de seguridad equivalen a la mitad de la reserva de trabajo.

Function workingReserve(itemCode, someDate) '' Inside here is a looping structure that adds up the requirements for the next six weeks (because that''s how long it takes between reorder and receipt). End Function Function safetyStock(itemCode, someDate) safetyStock = workingReserve(itemCode, someDate) / 2 End Function Function minimumOnHand(itemCode, someDate) minimumOnHand = workingReserve(itemCode, someDate) + safetyStock(itemCode, someDate) End Function

Me disculpo porque está escrito en VB, pero es de una función de Excel VBA.

En efecto, la función workingReserve se ejecuta dos veces en los mismos datos. El rendimiento puede mejorarse combinando la lógica empresarial de la función safetyStock () en la función minimumOnHand ().

Function minimumOnHand(itemCode, someDate) minimumOnHand = workingReserve(itemCode, someDate) * 1.5 End Function

En el código real, tengo comentarios en el código que explican la lógica comercial, pero los he omitido aquí por brevedad.


Como se mencionó en la pregunta Reescribir o Reparar , es posible que realice algunas refactorizaciones como la eliminación del código de duplicación de vez en cuando, a medida que las detecte.

Pero creo que este tipo de acción de "reescritura" se gestiona mejor cuando se detecta mediante una métrica , a partir de una herramienta de análisis estático de código , que:

  • detecta esos códigos duplicados
  • señala una tendencia (como que cada vez se detecta más código duplicado)

En ese caso, se puede priorizar una acción correctiva para centrarse en ese tipo de refactorización.

Pensándolo bien, me pregunto si podría ser el tipo de control de calidad al que se refiere Zig ;-)