Del post del otro día, el del «reflexionando sobre el Testing, en modelos Ágiles… pero con la realidad del código legacy«, generó bastante interés, e inquietud, la parte en la que decía que era muy difícil, yo no había visto nunca que terminar bien, rehacer de cero un sistema legacy (ya sabes, un software muy antiguo, que aún se evoluciona, que suele ser muy grande y que suele tener muy malas prácticas de diseño y programación).
Después de aquello, me paré a pensar que llevo casi toda my vida profesional trabajando con, para, código legacy, repleto de Walking Deads, con equipos que quieren mejorar, organizaciones que quieren cambiar, pero, como en prácticamente todos los sitios para los que he trabajado… que tenían mucho legacy, lo que limita mucho lo que nos gustaría hacer.
Quizá, como comunidad Ágil, o la que sea, le hemos dado poca atención a este tema, hablamos mucho de los casos ideales (que no irreales ni imposibles, ojo), los happy, pero poco de cómo llevarlos, hasta que punto, a la realidad mayoritaria que es… el legacy.
Tratar este tema, profundizar en este mensaje, ayudaría a aliviar la frustración que tiene mucha gente con la que trabajo, de sentirse impotente para poder aplicar las buenas prácticas que le gustaría. Ojo, aliviar la frustración, sin caer en el peligro de la complacencia, de pensar que cómo es difícil mejorar en un legacy… no hacer nada (ojo con esto, Lado Oscuro, cuídate de los «Es que nuestro caso es especial, somos diferentes»).
¿Por qué no veo realista volver a hacer un sistema antiguo?
Por supuesto, yo no soy el primero que se ha percatado de esto, y muchos de vosotros también sois consciente de ello.
En el post del Testing en legacy ya te dejé una referencia del Tío Bob hablando de ello, de lo difícil y arriesgado de rehacer de cero un sistema (habla de ello en el capítulo 1 de sus vídeos, en la parte que habla del equipo Tigre).
También en un comentario en el post de «Reflexionando sobre el Testing, en modelos Ágiles… pero con la realidad del código legacy» Tiago Cardoso dejaba un recordatorio a un viejo post de Spolski tratando igualmente lo imposible de rehacer un legacy, para hacerlo de nuevo, aunque suene muy sugerente 8y el impacto en el negocio que puede tener dicha aventura).
Reescribir el código desde cero, como dice Spolski es… uno de los peores errores estratégicos que puede cometer una empresa. Así de triste es la vida (en este sentido, claro, no me seáis tristes para todo).
Te he recopilado algunas de las razones de porqué plantearse rehacer un legacy de cero no es una buena idea…
- Mientras se hace el nuevo sistema de cero, el antiguo, el legacy, sigue evolucionando, el negocio no va a parar, y es tremendamente difícil ganar esa carrera, tener que llegar a la misma funcionalidad que tiene el viejo sistema mientras hacemos el nuevo.
- Y la opción de dejar de evolucionar el legacy, congelarlo, para replicarlo en un nuevo sistema es un suicidio, porque la competencia no va a parar y te pueden dejar fuera de mercado (hay muchos casos en la historia del legacy que han cometido este error).
- En sistemas legacy instalados en muchos clientes, si ya es complicado, mucho, instalar evoluciones del legacy, instalar a un cliente un sistema nuevo es, en muchas ocasiones… imposible. Y, a nivel de negocio y de cliente, poco justificable.¿Cómo se lo contamos a los clientes? Difícil, habría que justificarlo a nivel de nuevas funcionalidades, cuidarse mucho de que el nuevo sistema vaya como la seda…
- Es casi imposible sacar todo el conocimiento de años metido en un legacy para llevarlo a un nuevo sistema. Y no hablo solo de conocer todas las funcionalidades, sino también todos los algoritmos, los parches, el código que arreglaba yo que sé que cosa que aprendimos con mucho esfuerzo que no funcionaba, o cómo hacer que funcionara, etc.
- A nivel de negocio, es una gran inversión difícil de justificar, los clientes es difícil que paguen por la misma funcionalidad implementada de manera diferente.
- Por otro lado, ojo, estamos asumiendo que el nuevo sistema no va a tener malas prácticas de programación, cosa que es posible pero… cuidado, que ahí hay riesgo de que eso finalmente no sea tan cierto. Si el nuevo sistema lo hacen las mismas personas que hicieron el antiguo, es posible, quizá, que se repita mucho de lo que tenía en legacy.
Por ello, y con el objetivo de gestionar expectativas, es mejor no soñar con cómo sería la vida sin el legacy, porque ahí va a estar muchos años. Y empezar a pensar en cómo trabajar mejor con nuestro amigo el legacy y sus Walking Deads
Si tienes más razones que hacen difícil, casi imposible, rehacer un sistema grande de cero… ayudaría que las dejaras en un comentario.
Que la agilidad te acompañe.
- Debes crear apps sin saber programar (no hay que saber nada) + Crea Test con IA + Scrum es el nuevo Excel - 12 septiembre, 2024
- Las 6 técnicas prompting + 1ª Ley del Manager Oscuro + Mantenlo sencillo, estúpido - 5 septiembre, 2024
- Guía de Métricas Ágiles (versión agosto 2024) - 22 agosto, 2024
¿Entonces que hacer con el código sistema legacy? ¿Que estrategia aplicar para cambiarlo?
Pues en mi empresa lo hemos hecho. No una, sino dos veces. Y ahora vamos a por la tercera. Dicho esto, coincido con lo que dice el artículo, y con el de Joel también.
Las lecciones aprendidas darían para un libro. Un par de puntos como muestra:
1) Cada nuevo proyecto trajo a la empresa (de rebote) nuevas tecnologías y métodos de hacer las cosas: .NET, Scrum, etc. Eso, al margen del éxito del proyecto, fue bueno para la empresa.
2) El mayor problema al que se enfrenta el sistema nuevo es mantener la herencia del viejo (para que no te apedreen tus clientes), y a la vez cambiar la forma de hacer las cosas a mejor. Crear un nuevo producto aunando esos dos requisitos es… muy difícil.
Pero bueno, aquí estamos. No sé como hubiera sido si hubiéramos mantenido el código legacy, pero no me imagino un MES hecho en VB6 compitiendo hoy con otros en el mercado…
Querido Javier,
Tienes mucha razón en lo que dices, y yo, desgraciadamente estoy viviendo en esa pesadilla ahora mismo. Estoy en un equipo que se ha formado exclusivamente para rehacer desde cero un legacy que, además, es el producto clave de mi empresa y que lleva ya 20 años en el mercado con un montón de clientes en todo el mundo. Vamos una perita en dulce.
De todas las cosas que apuntas, la que ya llevo un tiempo notando con mayor desesperación es la primera de todas, el legacy evoluciona y no lo vamos a alcanzar nunca. Hace tiempo que soy consciente de ello pero la dirección aún vive en la fantasía de que «apretando» (ya sabes… Death March) llegamos a un MVP que, en fin, no es un MVP, es prácticamente toda la funcionalidad «básica» de un producto que lleva 20 años en el mercado. Todo esto en un plazo de 2 años… en fin… para qué te digo más.
Estamos intentando evitar errores del pasado y ese es una de las razones por las que yo vine a esta organización. Y bueno, la filosofía es radicalmente distinta, pero desde el principio, antes incluso de que yo llegara, la dirección decidió escoger a los mejores desarrolladores del antiguo legacy y crear con ellos el nuevo equipo, así que excepto una persona de mi confianza que me traje a esta aventura y yo mismo, los desarrolladores con experiencia son parte del equipo que hizo el legacy.
Obviamente yo tengo mi responsabilidad por no haberme percatado de todo eso antes de aceptar esta aventura.
Pero tengo mi sesgo al respecto por dos razones:
1. Martin Fowler habla en su libro de «Refactoring» que a veces simplemente el coste de evolucionar/refactorizar un código es mucho mayor que el de tirarlo a la basura y empezar de nuevo.
2. En una ocasión en el pasado logré dicha proeza. Y aquí es dónde quiero poner mi granito de arena. ¿Porqué logré sustituir completamente a un legacy con algo hecho desde cero? ¿Qué condiciones son buenas para hacerlo?
Pues las que se deducen de tu post:
– El legacy en cuestión, no era un producto que se vendía a clientes o que ya estaba instalado en muchos clientes. Se trataba de un sistema único que mi empresa, en su día, con un equipo anterior había desarrollado y venía evolucioniando para un cliente (una operadora móvil para más señas)
– El legacy evolucionaba, se le añadían funcionalidades nuevas pero a un ritmo más bien lento, no más de cuatro o cinco cambios al año que eran desarrollos muy pequeños.
– Él problema que querían solucionar era el rendimiento, la fiabilidad y sobre todo que los cambios que se hacían no implicaran código nuevo sino que el nuevo sistema pudiera aceptar cambios via configuración
– El equipo era completamente nuevo, excepto por una persona que conocía el sistema de pe a pa, había realizado los últimos evolutivos y era el primero en demandar que las cosas se hicieran de otra manera.
Las cosas de la vida, ese primer proyecto lo hice con el mismo grupo empresarial que ahora me ha ha llamado para esta aventura, aunque distinta filial. De hecho, pensaron en mí porque aquello salió bien y yo, no supe ver que eran bestias completamente distintas.
Gracias Javier por tu post y espero que os sirva de algo mi experiencia.
Los legacy están ahí, no te los puedes quitar de encima, y rehacerlo es seguramente perdiendo funcionalidad por todos los parches y algoritmos/trampa que se han ido generando a lo largo del tiempo. Ademas de las típicas quejas de que esto esta mal y no hacer nada al respecto para cambiarlo. Quejas y ni siquiera hacer nada para incluir soporte a poder hacer tests unitarios. Pero si se quiere, se puede ir aplicando buenas prácticas a medio largo plazo para todas aquellas funcionalidades nuevas, y a la larga aplicar alguna a aquellas zonas del código con mayor deuda técnica. Por ejemplo, lo vivido por mi. Primero dar soporte a Test unitarios, con la vista de querer aplicar TDD en un futuro. Crear Tests e ir practicando con el objetivo de hacer TDD real, el equipo va interiorizando la nueva forma de desarrollar. La pena es que a veces esta fase se tiene que hacer a escondidas poco a poco, para no delatar el incremento en coste de desarrollo y aprendizaje. Pueden pasar meses o 1 incuso un año para alcanzar niveles aceptables, y que los desarrollos actuales no sufran desvios. Luego compilación y ejecución de los test de forma automática, como mínimo. En nuestro ejemplo, Nosotros hemos pasado en 2 años a que los tests forman parte del código, forman parte del desarrollo, generar el test antes de picar código. Buenas prácticas dónde los números y el salto en calidad solo lo conoce quien lo vive. Una vez que tienes TDD más o menos interiorizado, cuando tienes que volver a un módulo antiguo del legacy repleto de deuda técnica, lo primero que harás será tratar de crear Tests para tener tu red de seguridad, refactorizar, y por último implementar el cambio o corrección. Poco a poco vas mejorando el código ya existente aplicando mejores prácticas. Y sin darte cuenta estarás actualizando aquel código que más se actualiza. No puedes rehacer un código legacy de cero, pero si puedes ir mejorando el existente si se tiene interés.
hola Javier muy buen post!, mi duda es la siguiente, aplica lo mismo par el caso de que ese sistema legacy sea provisto por una empresa externa? conviene embarcarse en desarrollar un sistema propio desde cero?
Me temo que lo que comenta Javier aquí ya lo decía hace muchos años John Gall, un pediatra norteamericano, en una ley bien conocida en los MBA, la Ley Gall:
«A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system»