¿Organizando código sucio y sin comentarios?

22

Me gustaría hacerle algunas preguntas sobre el código sucio. Hay algunos principiantes que codificaron en un proyecto mediano. El código es una gran bola de barro. No son programadores avanzados. Solo saben usar el teclado un poco sobre Java. Acaban de escribir código con 12 000 líneas en su clase principal, aunque 6 000 líneas pertenecen al propio NetBeans.

Mi trabajo es analizar el código y sugerir una buena forma de mantener el código. Mi idea es desechar el proyecto y comenzar uno nuevo con la metodología OOP. Recientemente recolecté algunas notas e ideas sobre el problema, de este sitio y de otros.

Ahora, tengo las siguientes preguntas:

  1. ¿Deberíamos reparar el código y cambiarlo a OOP? Ahora lo estamos depurando.
  2. El código no tiene comentarios, documentación, ningún estilo particular de programación, etc. Cambiarlo es realmente costoso y requiere mucho tiempo. ¿Qué podemos hacer al respecto?
  3. ¿Cómo puedo enseñarles a seguir todas las reglas (comentarios, POO, buena calidad de código, etc.)?
  4. El código es erróneo y propenso a errores. ¿Qué podemos hacer? ¿Pruebas? Casi escribimos dos o tres documentos A4 para su corrección, pero parece interminable.

Debería decir que soy nuevo con ellos. Creo que también he roto las reglas sobre agregar personas demasiado tarde al proyecto. ¿Crees que tengo que dejarlos?

Salivan
fuente
Esto debe dividirse en dos o tres preguntas, es demasiado amplio en este momento.
Jon Hopkins, el
2
¿Este proyecto está bajo control de versiones?
JBRWilkinson
2
¿Está el código actual en producción?
JeffO
Si Jeff ¡Es una producción, un proyecto de gestión para administrar problemas financieros!
Salivan
Lo siento JBR, no oyeron hablar de algo así. Simplemente hacer un cupé de códigos de copiar y pegar en todo el disco duro son sus técnicas para realizar el control de versiones.
Salivan

Respuestas:

36

Paso 0: copia de seguridad en SCM

Porque, como lo insinuó JBRWilkinson en los comentarios, el control de versiones es su primera línea de defensa contra el desastre (irreversible).

También haga una copia de seguridad de los detalles de configuración del software, procedimientos para crear entregables, etc.

Paso 1: prueba primero

Luego comience escribiendo pruebas :

  • por lo que funciona,
  • y por lo que falla

No importa lo que decidas hacer, estás cubierto. Ahora puedes:

  • comenzar desde cero y reescribir ,
  • o corregir la misma.

Mi consejo sería comenzar la arquitectura general desde cero , pero extraer del desorden las partes que validan los puntos de control y refactorizarlas como mejor le parezca.

Paso 2: verificar y monitorear

Configure un sistema de integración continua (para complementar el paso 0 y el paso 1 ) Y un sistema de inspección continua (para prepararse para el paso 4 ).

Paso 3: párate sobre los hombros de gigantes

(como siempre deberías ...)

Paso 4: limpiar

Eso no hace falta decirlo, pero en lugar de hojear el código usted mismo, es posible que desee simplemente ejecutar linters / analizadores estáticos y otras herramientas en la base de código rota para encontrar errores en el diseño y la implementación.

Entonces es posible que también desee ejecutar un formateador de código, que ya ayudará un poco con la limpieza.

Paso 5: Revisar

Es fácil introducir pequeños errores refactorizando o limpiando cosas. Solo se necesita una selección incorrecta y presionar rápidamente una tecla, y puede eliminar algo bastante importante sin darse cuenta al principio. Y a veces el efecto aparecerá solo meses después. Por supuesto, los pasos anteriores lo ayudan a evitar esto (especialmente mediante la implementación de un arnés de prueba fuerte), pero nunca se sabe qué puede pasar y lo que se escapará. Así que asegúrese de que sus refactorizaciones sean revisadas por al menos otro par de globos oculares dedicados (y preferiblemente más que eso).

Paso 6: Prepara tu proceso de desarrollo para el futuro

Tome todo lo anterior y conviértalo en una parte inherente de su proceso de desarrollo habitual, si ya no lo es. No permita que esto suceda nuevamente bajo su supervisión y trabaje junto con su equipo para implementar salvaguardas en su proceso y hacer cumplir esto (si eso es posible) en sus políticas. Haga que producir código limpio sea una prioridad.


Pero realmente, prueba . Una gran cantidad .

haylem
fuente
Una gran sugerencia: no importa qué daño haga si tiene pruebas que pueden detectar los problemas. Por supuesto, todos estamos asumiendo que ya tienen control de versiones ...
JBRWilkinson
@JBRWilkinson: ¡buen punto en realidad! De hecho, asumí completamente que lo hicieron.
haylem
2
Inicie el control de versiones primero; mejor tarde que nunca.
JeffO
@ Jeff O: sí, ya es lo que agregué a la respuesta.
haylem
Reescrito para aclarar después de las ediciones. Atribuciones izquierdas :)
haylem
15

Personalmente, no comenzaría este proyecto hasta que tenga a mano una copia de Trabajar eficazmente con código heredado . En serio, fue escrito para exactamente este tipo de cosas. Está lleno de estrategias para lidiar con código complicado, y entra en más detalles de los que puedo darle aquí.

Jason Baker
fuente
1
+1 para el uso de una amplia referencia externa que lo dice todo.
haylem
Desafortunadamente, aquí la gente no tiene idea de leer libros. Solo desarrollar un proyecto que funcione es todo lo que necesitan. Empecé a leer el libro que mencionaste, y también CODE COMPLETE 2. Déjame decirte que están maravillosamente escritos.
Salivan
1
@Salivan - Quizás simplemente no han tenido a nadie que los convenza de que vale la pena leer esos libros. Si tan solo hubiera una persona que trabajara con ellos que estuviera interesada en leer tales libros ...
Jason Baker
1
@Salivan: la clave es encontrar una victoria rápida o dos. Haga algo que tenga una recuperación casi inmediata. Al igual que el control de versiones, la próxima vez que alguien diga "cómo sucedió eso" puede buscarlo. Luego guíelos hacia algunas sugerencias de su lectura de su copia de WELC. No solo les arrojes el libro.
2
@Salivan Puede leer los libros para ellos y alimentarlos por goteo como consejo. Podrías convertirte en el gurú del equipo.
MarkJ
8

He estado allí varias veces. Mi regla es: si el software no es trivial (más de 1 semana de trabajo para el recurso que tiene) y funciona, consérvelo y continúe con la refactorización incremental.

Si el software realmente no funciona (una gran cantidad de errores, requisitos poco claros, etc.), entonces es mejor reescribirlo desde cero. Lo mismo si es bastante pequeño.

El punto en la refactorización (como en el libro de Fowler y el de http://www.industriallogic.com/xp/refactoring/ de Kerievsky ) es que mantiene el sistema funcionando, tal vez la refactorización tomará el doble de tiempo pero los riesgos son cero.

Reescribir desde cero podría presentar muchos riesgos, desde requisitos de malentendidos hasta una implementación incorrecta (después de todo, la mayoría del equipo será el mismo).

De hecho, vi que un procedimiento complejo se reescribía desde cero dos veces y todavía no funcionaba como se esperaba.

Uberto
fuente
También sugeriría escribir pruebas unitarias para métodos apropiados, si es posible. En primer lugar, ayudarán a definir claramente qué se supone que debe hacer el código , lo que ayudará al proceso de refactorización.
Michael K
2
No hace falta decir ... Considero que TDD es un requisito para cualquier código bueno (también conocido como el nuevo).
Uberto
Escribir desde el principio es una muy buena idea. Pero primero necesitas tener algunos diagramas del trabajo. Pero, ¿qué harás si tienes que analizar el código para extraer las relaciones? Además, el tamaño del proyecto lo hace imposible, o nos hará contratar a otros programadores.
Salivan
Test Driven Development es apreciado!
Salivan
"Pero, ¿qué harás si tienes que analizar el código para extraer las relaciones?" -> si este es el caso, significa que el proyecto no es pequeño ni está roto. Aka comenzaré a refactorizar una pieza a la vez. Ver también el método Mikado. danielbrolund.wordpress.com/2009/03/28/…
Uberto
2

Lo volvería a escribir por completo. A veces es imposible reparar dicho código. Otra opción es hacerlo funcionar, sin agregar nuevas características. Para enseñarle al equipo a escribir un buen código (bien diseñado, documentado, con pruebas), permítales corregir el código que tiene ahora. Deje que todos corrijan errores / revisen el código de otros desarrolladores, no su parte. Después de algunos intentos, comprenderán que es casi imposible revisar / corregir dichos códigos.

Agregar personas a proyectos tardíos ayuda muy raramente. Por lo general, rompe los plazos. Debe hacer todo lo posible para finalizar el proyecto con éxito, y luego pensar en irse.

duros
fuente
¿Cuánto costaría reescribirlo completamente versus mejorarlo iterativamente? ¿Qué enfoque daría resultados más rápido?
JBRWilkinson
@JBRWilkinson Depende. El enfoque iterativo es bueno cuando tienes un código de trabajo.
duros
1
@duros, por código roto, sí. Este código se ejecuta en producción.
2

Mi consejo será no desechar el código completo por completo. Este es el problema de la vida cotidiana que enfrentan todos los equipos de desarrollo. Ataca una parte del código a la vez. Arreglarlo, limpiarlo, documentarlo. Y luego pasar a la otra parte. Lo principal es mantener siempre a mano el código que se puede enviar. Reescribir todo el código desde cero tomará la cantidad de tiempo que se ha gastado hasta ahora y no habrá ninguna garantía de que sea mejor que el actual.
Pero también la gente debería evitar escribir el código de esta manera. Dedique más tiempo a las revisiones de códigos. Adaptarse a un estilo de codificación uniforme. Discuta el diseño primero y luego escriba el código. Tales cosas simples harán grandes cambios.

Buen blog que dice por qué Netscape está suelto

Manoj R
fuente
2
Comenzar un nuevo proyecto, mientras se actualiza / depura la versión anterior mientras tanto (y no puede evitar esto, así que no sueñe con eso) está tratando de disparar a múltiples objetivos en movimiento.
JeffO
"Atacar una parte del código a la vez" no funcionó, Manjo. Con un profundo dolor, el código contiene muchos errores. Siempre se convierte en otra cosa. Deberíamos atacar y destruir una parte del código y luego construirlo. Sugerí este pensamiento al gerente una vez, pero los codificadores deben dejar de escribir códigos nuevos.
Salivan
@Salivan ... no necesito escribir ningún código nuevo . Estoy seguro de que la gerencia está diciendo esto. Pero lo primero que debe hacer cuando está en un hoyo es dejar de cavar (no continúe cometiendo los mismos errores). Permitir que se creen más en estas condiciones es continuar cavando el hoyo. La parte difícil es cómo lograr que la administración y los codificadores comprendan los problemas.
SeraM
1

Si funciona, refactorícelo. Existen herramientas para ayudarlo a hacer eso. Si no funciona, use el comando de mejora de código mágico, es decir, deltreeen Windows resp. rm -rfen Linux

usuario281377
fuente
2
Sugerir "borrar completamente todo el código" es particularmente inútil: ¿tiene una respuesta más constructiva?
JBRWilkinson
Jajaja Estoy completamente de acuerdo contigo, ¡ammoQ!
Salivan
JBRWilkinson: Lo más probable es que hacer un nuevo reinicio sea un mejor enfoque que intentar que el desorden funcione y se limpie. Una empresa para la que trabajé lo intentó y, año tras año, desperdiciaron muchos recursos y no obtuvieron absolutamente nada.
usuario281377
@ammoQ, necesita el código antiguo para ver lo que realmente hizo, cuando se equivoca.
1
Thorbjorn: Estamos hablando de código que no funciona , ¿verdad? El análisis de código sucio y no comentado que no hace lo correcto me dice más sobre la condición mental de sus creadores que cualquier otra cosa.
user281377
1

¿Deberíamos reparar el código y cambiarlo a OOP? Ahora lo estamos depurando. [... contiene errores, no hay documentación ...]

He estado allí, tienes mis simpatías. Incluso escribí un artículo sobre esto que podría ayudarlo a obtener alguna perspectiva. Pero en resumen:

Si el código contiene mucha duplicación, debe reescribirlo. Si no hay una estructura discernible (sin interfaces claras, espaguetis), la refactorización fallará y probablemente debería reescribir.

¿Cómo puedo enseñarles a seguir todas las reglas?

Comience explicando por qué podrían querer hacer eso mostrándoles lo que pueden obtener personalmente. Cuando estén de acuerdo con esto y estén dispuestos a aprender, comience a enseñarles a usar shuhari .

Martin Wickman
fuente
Gracias martin "Comience explicando por qué podrían querer hacer eso mostrándoles lo que pueden obtener personalmente. Cuando estén de acuerdo con esto y estén dispuestos a aprender, comience a enseñarles a usar shuhari".
Salivan
0

Mi sugerencia es una combinación de las respuestas de @ duros y @Manoj R.

Comience desde cero, teniendo en cuenta crear un buen código / OOP / comentado / etc. esta vez, consulte / copie y pegue desde su código anterior. A medida que encuentre las partes malas de su antiguo código, vuelva a escribirlas / refactorícelas.

Si sus desarrolladores no están bien entrenados, creo que es bueno enviarlos a cursos. Es importante para la reentrenamiento regular en la industria de TI que cambia rápidamente

Jiew Meng
fuente