2008-11-17 10 views
24

¿Qué tan fanático es acerca de la eliminación del código duplicado?¿Cuán fanáticamente eliminas la Duplicación de código?

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 es la siguiente:

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

Respuesta

13

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.

+4

Si bien la codificación Huffman puede parecer el objetivo final, a uno le gustaría ver la minimización de la duplicación como un principio fuerte en lugar de una regla absoluta. –

4

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.

15

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.

1

Yo era bastante fanático para empezar, 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.

+0

Ver respuesta de CloneDR en este conjunto de respuestas. Puede manejar JSP. –

1

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.

Es muy poco lo que es peor que tener que recordar hacer cambios a la misma cosa en varios lugares.

+3

clases de ayuda, hay otro olor ... :) –

1

Como se mencionó en la pregunta Rewrite or Repair, puede hacer algunas refactorizaciones como la eliminación del código de duplicación de vez en cuando, a medida que las detecta.

Pero creo que este tipo de "reescribir" la acción está mejor administrado cuando se detecta por un metric, from a code static analysis tool, que:

  • detecta los códigos duplicados
  • puntos cabo una tendencia (como más y más duplicado el código tiende a detectarse)

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

Pensándolo bien, me pregunto si puedo ser el QA guy Zig se refiere a ;-)

+0

lol .. Nunca me gustaron los chicos de QA .. En el buen sentido ... :) – DragonBorn

+0

NB: ZiG borró su respuesta. Parafraseando, fue algo así como: "Trabajo duro para eliminar todo el código duplicado de mi módulo, y luego aparece un agente de control de calidad y me dice: '¡Oye! ¿Para qué necesitas eso?'". –

0

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

+0

interfaces de normalización –

1

Como la duplicación presta para copiar y pegar Siempre trato de evitar la duplicación o refactorización cuando ya existe una duplicación en el código existente.

14

Como se ha dicho, trato de vivir de acuerdo con el principio de "seco" - pero también me gustaría decir que hay otra condición en la que estoy a menudo reacios a eliminar la duplicación:

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

Ese conjunto de pruebas incluiría la llamando código 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.

+0

[Trabajar eficazmente con código heredado] (http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052) es un excelente libro que cubre el cambio seguro de código heredado (al encontrar por primera vez formas de escribir pruebas). – TrueWill

2

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 su código SECO.

Esto es un poco exagerado, pero no demasiado. Entre estar DRY y hacer que sus interfaces sean lo más estables y mínimas posible (Separation of Concerns), está en camino de ser un verdadero Software Engineer y no un Programador/Hacker.

2

VERY. 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 se necesita mantener un sentido de pragmatismo a veces, pero tiendo a inclinarme mucho hacia DRY.

4

Solía ​​ser bastante laissez faire al respecto - obviamente trate de evitar la duplicación donde sea posible, pero si necesita copiar las 15 líneas de código ocasionales de aquí para allá para guardar una refacturación de la tarde, eso probablemente sea correcto como siempre y cuando no lo habitúes.

Luego 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 "la 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é.

Por lo tanto, ESTO ha sido refactorizado. Y ahora soy un fanático de la extracción de engaños.

17

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, apenas empiezo 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.

que deje de llamar al proceso de "refactoring", porque eso es una palabra de moda desde el campo de XP, y esto hacía atrás en los años 80 con FORTRAN y C.

buena práctica de programación no tiene edad (y generalmente moderno, también).

Saludos,

-Richard

+0

Buen comentario, no sé por qué fue downvoted. http://dobbscodetalk.com/index.php?option=com_myblog&show=Porting-D-to-the-Mac-Pt.-2.html&Itemid=29 La abstracción prematura puede ser bastante mala porque hasta que realmente comiences a ver una tendencia, no sabes dónde dibujar líneas de abstracción. – dsimcha

+0

No sé por qué downvoted tampoco, ya que no quedó ningún comentario. Pero no eliminé mi respuesta simplemente porque así es como codigo, si eso agrada a todos o no. :-) Cheers -R – Huntrods

+0

estoy muy de acuerdo con dsimcha. Es difícil predecir el 100% de qué manera irá la tendencia. – sarsnake

7

Siempre trato de pensar primero por qué se duplica este código. 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 que no están relacionadas semánticamente, pero solo ocurre que tiene 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?).

+0

Ughm. Refactor, llama el código común de ambos. Cuando las reglas comerciales se desvían, elimine la llamada a la función. – igor

+1

+1 Hay lugares en mi código donde copio y pego secciones específicamente, tal vez con solo cambios en los nombres de variables y funciones, porque estas son reglas comerciales y secciones de comportamiento, y solo porque el ciclo suma todas las verificaciones en el sistema es lo mismo que el ciclo para sumar todas las tarjetas de crédito, eso no significa que sean iguales y deben cambiarse al mismo tiempo. –

4

I "m más o menos un psico al respecto Si hago algo más de una vez me refactorizar periodo signo de exclamación

5

Trabajamos en ello Realmente ayuda a 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 el código duplicado, copias exactas y casi errores, en sistemas fuente grandes, parametrizados por la sintaxis de idioma. Es compatible con Java, C#, COBOL, C++, PHP y muchos otros idiomas. Lo usamos nosotros mismos para ayudar a administrar nuestro propio código.

+0

¿Cómo se compara con la detección de duplex de TeamCity? – ripper234

+1

+1 por mencionar una herramienta y su propia experiencia con ella. –

+0

@ ripper234: los documentos de Team City no son muy claros acerca de las capacidades de su detector. Parece encontrar duplicados exactos y encontrar cuasiaccidentes en los que tokens individuales se reemplazan por otros tokens individuales. CloneDR encontrará duplicados exactos, y encontrará casi fallos en los que una estructura de código es reemplazada por otra (por ejemplo, una expresión completa es reemplazada por una expresión completamente diferente), y determinará cuándo una sola sustitución de una estructura de código complejo puede ser sustituido muchas veces. También encontrará conjuntos de clones con replicación arbitraria (por ejemplo, 1000x). –

0

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 

Pido disculpas por el hecho de que 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, no tengo comentarios en el código que explica la lógica de negocio, pero ellos se han omitido aquí por razones de brevedad.

Cuestiones relacionadas