¿Cómo arreglar el patrón copiar / pegar?

16

Donde trabajo, las personas (consultores) se sienten presionadas para lanzar funciones lo más rápido posible. Entonces, en lugar de pasar demasiado tiempo pensando en cómo hacer las cosas de la manera correcta o porque no quieren romper nada, el código se copia de diferentes módulos y se modifica.

No es fácil evitar esto, ya que la base del código está abierta a toda la empresa. Mucha gente trabaja en esto.

Ahora que el desorden ya existe, ¿cuál es la mejor manera de eliminar esas redundancias sin romper demasiado?

LennyProgrammers
fuente
3
Lo más molesto es cuando el código se copia / pega de algún sitio e incluso los comentarios no se eliminan. Entonces puedes encontrar: "// Gracias por eso Carlo" ... Y cuando se lo señalas, se ríen y dicen: "¡Déjalo!))". Eso no es profesional y triste !!!
CoffeeCode
2
no son solo consultores
AndersK

Respuestas:

14

Una parte de la respuesta es la refactorización .

Primero, comience a escribir pruebas unitarias para asegurarse de no romper accidentalmente nada con sus cambios. Luego, comience a mejorar el diseño, elimine las duplicaciones, etc. en pequeños pasos, ejecute las pruebas de su unidad después de cada paso, solucione cualquier problema si alguna de las pruebas falla o revierta de inmediato si se encuentra con un problema mayor del que puede resolver fácilmente.

La otra parte es la educación .

Se debe enseñar a las personas a no dejar atrás el código incorrecto. Esta es ciertamente una batalla a largo plazo, ya que los hábitos y los procesos de pensamiento son difíciles (a veces incluso imposibles) de cambiar . Sin embargo, sin él, continuará recibiendo un suministro interminable de códigos incorrectos que gritan para ser refactorizados.

Puede optar por realizar revisiones de código de grupo para abrir una discusión sobre los hábitos de codificación buenos y malos, y difundir los méritos de los primeros. No es suficiente decir "debes (no) escribir código como este", debes convencer a las personas con lógica y hechos concretos. Por ejemplo, "si tiene este método duplicado en la base de código n veces, ¿qué cree que es probable que si se encuentra un error en ese método, se solucionará en cada copia del código del método?"

Es posible que su empresa también necesite revisar los incentivos y los criterios de aceptación para los consultores : si pueden salirse con la suya al escribir código descuidado, seguramente seguirán eligiendo el camino más fácil. Si la empresa sigue valorando la "entrega rápida" a lo largo del mantenimiento a largo plazo, nada cambiará :-( Por lo tanto, es posible que deba analizar esto también con la gerencia. Una forma de hacerles entender es esto: refactorizar significa mantener el código limpio, fácil de usar. entender y mantener, omitir la refactorización es como acumular deudas en su tarjeta de crédito. Puede salirse con la suya por un tiempo, pero si no está administrando activamente sus hábitos de compra y deudas, inevitablemente se desmoronará sobre sus hombros algún día. En la vida de un proyecto de software, la bancarrota es cuando el proyecto se vuelve imposible de mantener: se hace más fácil reescribirlo desde cero que agregar una nueva característica a la base de código existente. O los usuarios se cansan tanto con el nivel inferior de soporte y características que simplemente cambian a la competencia.

Péter Török
fuente
44
"Primero, comienza a escribir pruebas unitarias para asegurarte de no romper accidentalmente nada con tus cambios". Woah, bombea los frenos allí. Realmente no me gusta cómo todos en los sitios de SE lanzan esta línea en su respuesta con tanta indiferencia. Esto es extremadamente difícil de entender y no es tan casual como el 99% de los usuarios que sugieren que lo haga.
@ Sergio Tapia: cierto, pero no se puede refactorizar sin él. Bienvenido a la realidad, alrededor del año 2011.
Scott Whitlock
1
@ Sergio, si te refieres a que el código heredado de prueba de unidad es difícil, no podría estar más de acuerdo. Me complace extender la oración citada como "Primero, debe comenzar la ardua y estresante tarea de escribir pruebas unitarias ..." :-) Sin embargo, si quiere decir que, dado que las pruebas unitarias son difíciles, uno debería intentar sobrevivir sin No estoy de acuerdo (basado en la experiencia práctica, no en la teoría). No hay un camino real para mantener el código heredado.
Péter Török
9

Como parte de la educación, como dijo @Peter, puede introducir un detector de copiar y pegar como PMD y usarlo como parte de su desarrollo cíclico para ayudar a hacer cumplir esta parte de sus estándares de codificación.

Asegúrese de que el estándar de codificación de sus proyectos cubra este patrón, de modo que tenga una línea de base para comenzar las discusiones.

rsp
fuente
1
Me gusta esto, agradable!
ozz
¿Es posible exigir el cumplimiento de un estándar de codificación en el contrato de un contratista?
Armand
1
@Alison Puede exigir que se adhiera a lo que quiera, siempre y cuando lo indique por adelantado, no debería tener ningún problema. Como contratista, me adhiero a cualquier requisito de desarrollo que tengan las empresas en las que trabajo, una de ellas es consistente con sus estándares de codificación. La revisión del código antes de enviarlo a la troncal también podría ayudar a resolver esto
DBlackborough
Gracias, después de su publicación, también encontré clonedigger.sourceforge.net para Python / Java.
LennyProgrammers
@ G3D tiene sentido; ¿Te gusta tener un estándar de codificación para trabajar? Mi problema con las revisiones de códigos como una forma de aceptación es que, como contratista, me preocuparía que el código pudiera ser rechazado por razones arbitrarias (por ejemplo, políticas o cambios en el presupuesto)
Armand,
8

las personas (consultores) se sienten presionadas para lanzar funciones lo más rápido posible

No tienes un problema técnico, tienes un problema social. De hecho, tienes un problema de gestión.

No es fácil evitar esto, ya que la base del código está abierta a toda la empresa. Mucha gente trabaja en esto.

El "código base está abierto a toda la empresa" no es un problema. No importa

Lo que importa es que existe un sistema de recompensa de gestión para copiar y pegar. La causa raíz es que las personas son recompensadas (es decir, pagadas, elogiadas, promovidas o extendidas) por copiar y pegar.

No puede romper esto sin cambiar fundamentalmente la cultura de "presionar para lanzar funciones lo más rápido posible" a "recompensado por hacer los cambios apropiados y bien probados en la base de código".

Tienes que

  1. Comience en la parte superior, con los gerentes que refuerzan las recompensas. Debe exponer la práctica actual y documentar los costos y riesgos. Debe proponer una alternativa que reduzca los costos y los riesgos.

  2. Debe documentar y exponer sin descanso los costos y riesgos para el resto de su mandato en esa organización. Implacable.despiadado. Basado en hechos. Costo y riesgo. Cada semana más costos y más riesgos de copiar y pegar.

  3. Tendrá que ayudar a los gerentes a tomar el crédito del nuevo enfoque que los hará verse bien y será ignorado.

Es muy importante reducir copiar y pegar. Pero es difícil cambiar la cultura de una organización. Debe proporcionar muchos datos y debe presentar el caso una y otra vez ante los gerentes que no están de acuerdo con usted.

S.Lott
fuente
1
+1 especialmente para "Tendrás que ayudar a los gerentes a dar crédito al nuevo enfoque que hará que se vean bien y serás ignorado". Es mejor estar preparado para que con demasiada frecuencia esto sea realidad :-(
Péter Török
@ Péter Török: demasiadas personas se dan por vencidas en esto. No recopilan los hechos sobre los problemas causados ​​por copiar / pegar o no siguen presentando el caso ante la gerencia una y otra vez.
S.Lott
Sé que aquí hay un problema no técnico más profundo. Pero es un problema que nadie a quien le importa puede solucionarlo en el corto plazo. Es como un error en una biblioteca de terceros que necesita solucionar.
LennyProgrammers
@ Lenny222: Tu comentario tiene poco sentido. "Es un problema que nadie a quien le importa puede solucionarlo en el corto plazo" está claro en la pregunta. ¿Qué significa este comentario? ¿Qué falta en la respuesta? ¿Qué más necesitas?
S.Lott
Este será un proceso de educación continua.
JeffO
5

Tengo una base de código ahora que estaba empezando a pudrirse a partir de eso. Tenía más de 10 funciones estáticas por módulo que eran básicamente idénticas a las mismas funciones estáticas en otros módulos. Cada uno se comportó de manera lo suficientemente diferente como para garantizar una nueva encarnación en aras de hacer las cosas lo más rápido posible.

Hoy, tuve que agregar otra característica y simplemente no pude soportarlo más. Creé una nueva biblioteca, combiné las más de 100 funciones en 10 funciones reentrantes que alteran ligeramente su comportamiento en función de los indicadores de bits y luego escribí una serie de pruebas para asegurarme de que los cambios en esa biblioteca no rompieran nada más.

Tiempo total empleado: 4 horas. Estaba listo para una maratón de 20 horas si era necesario y me sorprendió lo rápido que pude controlar un desorden cada vez mayor. Como beneficio adicional, fue más fácil solucionar posteriormente un montón de problemas de dependencia del encabezado. Además, dado que muchas de nuestras cosas patentadas ahora están en objetos estáticos para vincular, podemos darles a nuestros clientes que obtienen acceso al código fuente más de lo que lo hicimos anteriormente.

Mi consejo: muerde la bala y vuelve a factorizar ese desorden ahora antes de hacerlo, realmente se pone mal . Probablemente no tomará tanto tiempo como crees, pero crea una nueva rama para ti solo por si acaso.

Además, aún puede copiar / pegar para obtener funciones al mismo tiempo que soluciona el problema fundamental. Cuando haya terminado, simplemente extraiga las cosas pegadas y use la nueva biblioteca en su lugar.

Tim Post
fuente
Curioso, ¿encontraste alguno que fuera idéntico?
JeffO
@ Jeff - Sí, unos pocos. Pero, sobre todo, el patrón mostró que la duplicación era el resultado de alguien que quería qué (debería ser) el código de la biblioteca para hacer algo un poco diferente.
Tim Post
5

Estoy de acuerdo con las respuestas dadas hasta ahora. Debieras:

  • crear pruebas unitarias
  • refactor
  • educar
  • esforzarse por codificar los estándares y detectar violaciones

Pero, por otro lado, debe observar qué hace que las personas copien, peguen y arreglen eso.

  • es posible que las personas no puedan reutilizar el código de una buena manera porque está acoplado a mucho
  • la gente puede no saber que hay una biblioteca que pueden usar
  • Es posible que el código de la biblioteca no sea lo suficientemente genérico y hornear su propia versión es mucho más fácil que usar una biblioteca existente
  • Es posible que no haya una buena estrategia de control de versiones (no de control de código fuente) y cambiar una biblioteca genérica podría hacer que también se prueben muchas otras aplicaciones.

Por lo tanto, creo que para detener el patrón de copiar / pegar, debe facilitar la reutilización.

  • Hacer bibliotecas reconocibles y bien documentadas
  • hacer que las bibliotecas sean independientes de todo
  • pensar en una buena estrategia de versiones
  • asegurar compatibilidad hacia atrás
  • pensar en la fácil extensibilidad de las bibliotecas

lea las pautas de diseño del marco

Espero que esto ayude.

KeesDijk
fuente
3

Existe una fuerte actitud de "copiar y pegar considerado perjudicial". Creo que es bueno, pero va un poco demasiado lejos. Copiar y pegar como un ejercicio para descubrir las similitudes y diferencias entre dos métodos o clases, como un paso en el proceso de triangulación, creo que es saludable. Pero detenerse antes de la triangulación completa, de eliminar la duplicación introducida por copiar y pegar, es realmente dañino.

Si puede encontrar formas de usar esa actitud más matizada, decirle a los desarrolladores que no "eso es malo", sino más bien "eso está incompleto, ¿puede trabajar conmigo para completar la refactorización?", Entonces es posible que tenga conversaciones más constructivas.

Carl Manaster
fuente
2

Me preocupa el mismo problema aquí, y mi opinión es: no intentes evitarlo por adelantado, solo refactoriza cuando se pone demasiado mal.

El módulo en el que estoy trabajando actualmente en startet como una copia de otro módulo, ahora estoy cambiando todo lo que debe ser diferente. Una vez hecho esto, y el nuevo módulo esté terminado, lo compararé con el módulo original y descubriré qué partes están más o menos sin cambios y deberían trasladarse a una biblioteca, clase principal abstracta, etc.

usuario281377
fuente
2

Quien está a cargo tiene la culpa. No se puede esperar que una persona revise cada línea de código, pero sí establece los estándares y los plazos.

Los contratistas (o cualquier persona que tenga un proyecto a corto plazo) pueden ocupar el puesto en el que solo se les compensa por hacer que funcione la primera vez. Hay algún incentivo para hacerlo lo antes posible. Es posible que el código copiado nunca necesite modificarse y, si lo es, no será por ellos.

Podrías intentar forzarlos a arreglarlo en su propio tiempo. Luego comenzarán a hacerlo desde el principio, pero luego se tomarán un tiempo excesivo para hacer las cosas. Creo que AmmoQ tiene la idea correcta de refactorizar cosas que están causando problemas.

JeffO
fuente
Estoy de acuerdo. La cuestión es que los gerentes de proyecto no tienen incentivos para pagar más por un código bien diseñado. Si tengo que perder una semana, no me cobran.
LennyProgrammers
@ Lenny222: lo que puede hacer es elegir sus lugares en un proyecto para mejorar el código. El punto de venta para el primer ministro no ocurrirá hasta que regresen (generalmente con la cola entre las piernas) y necesiten lo que sientan será un cambio importante solo para escuchar su respuesta de 'no se preocupe, construimos esa parte para ser más flexible' . Eventualmente pueden aprender que hay una manera correcta de hacer las cosas y administrar las expectativas del cliente. Todos quieren un software de calidad, pero pocos saben lo que realmente cuesta.
JeffO
1

La única forma de eliminar el código de copiar / pegar es revisar el código (en mi humilde opinión), pedirle a una persona (o preferiblemente más) que revise el código y cuando encuentre un código que parece provenir de una acción de copiar / pegar, permita que el programador refactorice.

AndersK
fuente
1

Como se sugirió, esto es principalmente un problema en la organización. Intente comenzar educando a las personas (no olvide la capa de administración directa sobre su posición). Es de gran ayuda comenzar a tener una o dos personas en su tren y dejar que el virus se propague. Cuando la mayoría piense que esta es una buena idea, descríbala e intente introducir revisiones para garantizar que se mantenga así. Este es un proceso muy lento y tedioso, pero simplemente no puede cambiar rápidamente. Al principio costará tiempo extra, por lo que es importante que la gerencia conozca y respalde el objetivo a largo plazo.

@Anders K. Las revisiones son un buen medio para mantener la práctica en su lugar. Al obligar a las personas a escribir código que no creen en él crea mucha fricción. Volverán a caer en la vieja habitación tan pronto como sea posible. Creo firmemente que deberías comenzar con la educación para ganar impulso.

refro
fuente