He visto algunas veces el libro Trabajar eficazmente con código heredado recomendado. ¿Cuáles son los puntos clave de este libro?
¿Hay mucho más para lidiar con el código heredado que agregar pruebas de unidad / integración y luego refactorizar?
He visto algunas veces el libro Trabajar eficazmente con código heredado recomendado. ¿Cuáles son los puntos clave de este libro?
¿Hay mucho más para lidiar con el código heredado que agregar pruebas de unidad / integración y luego refactorizar?
Respuestas:
El problema clave con el código heredado es que no tiene pruebas. Por lo tanto, debe agregar algunos (y luego más ...).
Esto en sí mismo requeriría mucho trabajo, como señaló @mattnz. Pero el problema especial del código heredado es que nunca fue diseñado para ser comprobable . Por lo tanto, generalmente es un gran lío enrevesado de código de espagueti, donde es muy difícil o francamente imposible aislar piezas pequeñas para realizar pruebas unitarias. Entonces, antes de las pruebas unitarias, debe refactorizar el código para que sea más comprobable.
Sin embargo, para refactorizar de manera segura, debe realizar pruebas unitarias para verificar que no haya roto nada con sus cambios ... Esta es la trampa 22 del código heredado.
El libro le enseña cómo salir de esta trampa haciendo los cambios mínimos y más seguros al código solo para habilitar las primeras pruebas unitarias. No se pretende que el diseño sea más agradable, solo para permitir pruebas unitarias. De hecho, a veces hacen que el diseño sea más feo o más complejo. Sin embargo, le permiten escribir pruebas, y una vez que tenga las pruebas unitarias en su lugar, tiene la libertad de mejorar el diseño.
Hay muchos trucos para hacer que el código sea comprobable: algunos son obvios, otros no. Hay métodos que nunca hubiera pensado en mí, sin leer el libro. Pero lo que es aún más importante es que Feathers explica lo que precisamente hace que una unidad de código sea comprobable. Necesita cortar dependencias e introducir barreras en su código, pero por dos razones distintas:
Cortar dependencias de forma segura puede ser complicado. Introducir interfaces, simulacros e Inyección de dependencias es un objetivo limpio y agradable, pero no es necesariamente seguro hacerlo en este momento. Entonces, a veces tenemos que recurrir a la subclase de la clase bajo prueba para anular algún método que normalmente, por ejemplo, iniciar una solicitud directa a un DB. Otras veces, incluso podríamos necesitar reemplazar una clase / jar de dependencia con una falsa en el entorno de prueba ...
Para mí, el concepto más importante introducido por Feathers son las costuras . Una costura es un lugar en el código donde puede cambiar el comportamiento de su programa sin modificar el código en sí . La construcción de costuras en su código permite separar el fragmento de código que se está probando, pero también le permite detectar el comportamiento del código que se está probando incluso cuando es difícil o imposible hacerlo directamente (por ejemplo, porque la llamada realiza cambios en otro objeto o subsistema , cuyo estado no es posible consultar directamente desde el método de prueba).
Este conocimiento le permite notar las semillas de la capacidad de prueba en el montón de código más desagradable, y encontrar los cambios mínimos, menos disruptivos y más seguros para llegar allí. En otras palabras, para evitar hacer refactorizaciones "obvias" que tienen un riesgo de romper el código sin que lo notes - ya que ni aún tiene las pruebas de unidad para detectar eso.
Formas rápidas de obtener los puntos clave de trabajar eficazmente con código heredado
Trabajo en una base de código de millones de líneas de código, algunas que datan de la década de 1980. Es solo software, por lo que es solo cuestión de escribir algunas pruebas unitarias, para que pueda ir y refactorizarlo, y hacerlo mucho mejor.
La palabra clave aquí es simplemente: es una palabra de cuatro letras que no pertenece al vocabulario de ningún programador, y mucho menos a una persona que está trabajando en sistemas heredados.
¿Cuánto tiempo cree que toma escribir una prueba unitaria, para probar una hora de esfuerzo de desarrollo? Por el bien de la discusión, digamos otra hora.
¿Cuánto tiempo se invierte en ese sistema heredado de hace 20 millones de líneas? Digamos, 20 desarrolladores durante 20 años por 2000 horas / año (trabajaron bastante duro). Ahora escojamos un número: tienes nuevas computadoras y nuevas herramientas, y eres mucho más inteligente que los muchachos que escribieron esta pieza de $% ^^ en primer lugar, digamos que vales 10 de ellas. ¿Tienes 40 años hombre, bueno, tienes ...?
Entonces la respuesta a su pregunta es que hay mucho, mucho más. Por ejemplo, esa rutina de 1000 líneas (tengo algunas que son más de 5000), es demasiado compleja y es una pieza de espagueti. Solo tomaría (un par de palabras de cuatro letras más) un par de días re-factorizarlo en unas pocas rutinas de 100 líneas y unos pocos ayudantes de 20 líneas más, ¿verdad? INCORRECTO. Oculto en esas 1000 líneas hay 100 correcciones de errores, cada una un requisito de usuario indocumentado o un oscuro caso marginal. Son 1000 líneas porque la rutina original de 100 líneas no hizo el trabajo.
Debe trabajar con la mentalidad " si no está roto, no lo arregle ". Cuando está roto, debe tener mucho cuidado al arreglarlo, a medida que lo mejora, para que no cambie accidentalmente otra cosa. Tenga en cuenta que "roto" puede incluir código que no se puede mantener, pero que funciona correctamente, eso depende del sistema y su uso. Pregunte "qué sucede si lo arruino y lo empeoro", porque un día lo harás, y tendrás que decirle al jefe de los jefes por qué elegiste hacer eso.
Estos sistemas siempre se pueden mejorar. Tendrá un presupuesto para trabajar, una línea de tiempo, lo que sea. Si no lo haces, ve y haz uno. Deje de mejorarlo cuando el dinero / tiempo se haya agotado. Agregue una función, dese tiempo para mejorarla un poco. Solucione un error, nuevamente, dedique un poco de tiempo extra y mejore. Nunca lo entregue peor de lo que era cuando comenzó.
Hay dos puntos clave para quitar del libro.
Como han señalado otros respondedores, tratar de actualizar de forma preventiva su código heredado existente es una tontería . En cambio, cada vez que tenga que hacer un cambio en el código heredado (para una nueva función o una corrección de errores), tómese el tiempo para eliminar su estado heredado.