Técnicas para mantener al legacy code bajo control

Somos desarrolladores de software, tenemos que leer código gran parte de nuestro día, tenemos que usar código legado y tenemos que mantenerlo, incluso añadir nuevas funcionalidades. ¿Cómo lo hacemos? ¿Cómo abordamos cambios en legacy code de manera eficiente? Pues no tengo ni idea, pero sí sé que si tengo una buena caja de herramientas cerca mi trabajo será más sencillo. Por eso en este post vamos a llenar nuestra caja de herramientas con algunas técnicas que nos ayudarán a trabajar un poco mejor con legacy code. No se trata de usarlas todas siempre, sino de tenerlas a mano para cuando nos hagan falta.

Hotspot analysis

Ya sabemos que la mejor manera de acabar con el legacy es ir paso a paso, partido a partido, estamos en una maratón y tenemos que ir mejorando progresivamente: añadiendo pruebas, haciendo refactoring seguro, extrayendo funcionalidad, eliminando funcionalidad,… al final el tiempo es nuestro mejor aliado.

¿Por dónde empezamos?

Existen herramientas como code climate o SonarQube que pueden darnos una idea aproximada de en que punto estamos y cuál es la cantidad de deuda. Estas nos dan informes detallados de donde están los problemas más graves, pero cuidado: ¡Ir a los problemas graves es un error! al menos en un primer momento. Tenemos que priorizar. El simple hecho de que una parte del código tenga una métrica pésima, no significa que tengamos que ir primero a ella, tenemos que combinar este informe de deuda con las partes más cambiadas de nuestro código. Esto es llamado Churn

Pensémoslo, si hay código que es un lío, pero no lo hemos tocado en 2 años, ¿a quién le importa? Vamos a centrarnos en estos puntos del recuadro y poco a poco aprenderemos más sobre la aplicación, el negocio, la infraestructura,… y podremos afrontar los nuevos retos que se nos presenten.

Una manera sencilla de ver los archivos más modificados en git es haciendo algo como esto:

git log --format=format: --name-only --since=12.month \  
| egrep -v '^$' \  
| sort \  
| uniq -c \  
| sort -nr \  
| head -50

Cruzando datos o usando herramientas como Code Climante o similar podremos tomar decisiones más inteligentes y de verdad invertir esfuerzo en donde más nos compense.

Otras herramientas que pueden sernos útiles para cruzar estos datos son churn-php , code-forensics o codescene.

Mikado Method

Esta técnica es efectiva cuando tenemos un objetivo claro, o cuando queremos saber cuanto nos llevaría hacer un refactor “grande” y no queremos perdernos por el camino.

Lo primero es coger lápiz y papel o algo como https://excalidraw.com/ para anotar. Ahora lo primero que hacemos es escribir el objetivo y rodearlo con 2 círculos. Si para realizar ese objetivo necesitamos otra tarea: hacemos un git reset de lo que llevamos, la anotamos en otro circulo y empezamos de nuevo.

Mikado method

En algún momento llegaremos a un paso que podamos hacer sin problemas. Lo hacemos, lo tachamos y cogemos otra tarea.

Este método sirve para no perder el foco de por donde vamos y cuanto nos queda. Del mismo modo con este método también podemos tener un análisis de cuanto nos costaría llevar a cabo un objetivo.

Mikado no solo sirve para refactorizar, sino que también nos ayuda no estresarnos, porque solo tenemos en la cabeza lo que estamos haciendo en este momento, no tenemos que recordar todo. Quien me conoce sabe que hago muchas veces la metáfora de la “mochila” que vamos cargando a medida que avanzamos por el camino, por lo que es importante tener la mochila lo más vacía posible.

Una de los errores más comunes a la hora de refactorizar es que nos “vamos enfangando”. Es decir, queremos arreglar algo que está mal, pero entramos en otro método y nos cuenta de otro smell muy claro que podemos limpiar. Nos ponemos con este nuevo smell y nos damos cuenta de que tenemos que tocar allí,… esto es lo que se llama efecto túnel. Usando Mikado, evitamos ese efecto, porque nos centramos en la tarea que tenemos que hacer y si encontramos algo nuevo solo tenemos que anotarlo.

Over committing

Como ya hemos comentado antes, cuando trabajamos con legacy code es fácil perder el foco. O peor aún, llegar a un camino sin salida y no poder volver atrás porque “perdemos” demasiados cambios que si funcionan.

Tenemos que tener un enfoque más seguro, podemos apodarlo “guardar partida”. La idea es tener <<puntos de control>> a los que volver si llegamos a un camino sin salida. Aquí es donde le sacamos partido a git, vamos a ir creando puntos de control cada vez que llegamos a un punto donde hemos conseguido algo.

Aquí podemos tomar un enfoque práctico, por ejemplo un script que haga un commit cada 5 minutos o podemos si usamos mikado ir haciendo commit cada vez que una tarea esté resuelta.

En mi caso optaría por algo parecido a lo 2º, es decir, ir poco a poco haciendo commits cada vez que vamos alcanzando hitos. Poniendo buenos mensajes de commits para saber que estoy haciendo con la historia.

La mejor manera de acostumbrarnos a hacer commits más pequeños es haciendo katas y poniendo un timer que haga reset cada 5 minutos.

Katas

Hacer cambios en código de producción, con pocos tests, donde ese código nos da de comer,… puede ser arriesgado a veces. Por eso debemos practicar, igual que Rafa Nadal entrena cada día, nosotros debemos hacer algo parecido.

Trabajar con Legacy Code es una skill que se aprende. Leer código “sucio”, sin documentación es algo que podemos desarrollar.

En nuestro código de producción tenemos mucha complejidad y no controlamos al 100% que es lo que puede pasar, quizás sea buena idea tener un playground. Un lugar que controlemos y donde podamos intentar esa técnica que hemos leído en el libro “working effectively with legacy code”, u obligarnos a hacer commits más pequeños, probar técnicas de testing como snapshop testing,…

Esta es una pequeña recopilación de katas sobre refactoring https://github.com/jeslopcru/refactoring-katas-php las podemos encontrar en cualquier lenguaje. Algunas de mis preferidas son:

  • Trip Service Kata: de mis preferidas, ya que aprendemos a inyectar dependencias. Simula llamadas a una BD y tenemos que aprender a hacer tests sobre ese código sin llamar a la BD.
  • Trivia Kata: un código legacy a tope, donde podemos aprender la técnica “Golden Master”
  • Gilded-rose: un clásico para empezar con esto del refactoring.

Sobre katas hay un monton por Internet, si queréis estar al día o conocer nuevas katas Emily Bache tiene muchísimas.

Approval Testing

Esta técnica parece mágica y como todo poder hay que usarla con responsabilidad. Es una forma de escribir test para luego poder refactorizar el código.

La técnica se basa en generar una salida de la que podamos crear una “foto”, ayudarnos de la cobertura de código para ver que hemos cubierto todo el código con tests y añadir mutation testing para verificar los “snapshot que hemos creado.

Podemos encontrar más información con otros nombres como: Characterisation Test, Golden Rule o Snapshot testing.

En PHP tenemos librerías como spatie/phpunit-snapshot-assertions o KigaRoo/snapshot-testing para crear snapshots. Para la cobertura de código XDebug es casi el standar por defecto. Para el mutation testing tenemos librerías como infection/infection, aunque la forma más sencilla de ver si nuestros test tienen una buena red de seguridad es comentando alguna linea suelta y ejecutando los tests. Si los test siguen en verde, tenemos que seguir trabajando con ellos.

Una de las ventajas de esta técnica es que no tenemos ni siquiera que leer el código para saber que está haciendo, nuestro objetivo es tener un buen snapshot para empezar a refactorizar de forma segura.

Aunque este tipo de test no son para siempre, sino solo cuando estamos inmersos en modificar un código legacy, una vez que empecemos a darle cariño a ese código tendremos que crear tests más a medida (unit testing, integration,,…). El Approval testing es temporal.

Architecture Decision Records (ADR)

Normalmente cuando estamos trabajando con Legacy code tenemos un problema de fondo que es la falta de contexto.

Cuando no sabemos porque se ha optado por una solución, se ha escogido una arquitectura o una pieza de infraestructura. Siempre entramos en dilemas de si cambiar esa pieza, mantenerla, que ventajas/desventajas existen con cada decisión,… a veces podemos ver el “git blame” y preguntar, otras incluso hacer arqueología de “git log” para saber cuando se añadió, pero todo esto conlleva un esfuerzo, un tiempo y a veces no es nada fácil.

Hay una técnica que parece obvia pero que pocos equipos usan y esa técnica es escribe un documento con la solución escogida, alternativas con sus pros y contras, ponle una fecha, básicamente describe el porqué escogiste esta solución y listo.

ADR

A esto se le llama Architecture Decision Records. Aquí tienes por ejemplo ADR del gobierno británico https://github.com/ministryofjustice/form-builder/tree/master/decisions

Como sabemos, lo difícil no es solo hacer este documento, sino tenerlo controlado, compartido, visible para el resto del equipo. Es un buen hábitoque fomentemos el hecho de escribir documentación como esta para que todo el equipo estemos al día de las decisiones.

Si te interesa el tema, hay algunas utilidades como npryce/adr-tools creada por el coautor de “Growing Object-Oriented Software, Guided by Tests” (un gran libro, por cierto).

Conclusiones

Trabajar con legacy code supone a veces mucha presión, un cambio puede hacer que todo se rompa sobre todo cuando no sabemos hacer “rollback”. Aprendiendo técnicas como esta, aliviamos un poco esa presión y afrontamos esos cambios en el legacy code de otra manera, poco a poco con seguridad. Con seguridad, porque ya tenemos una serie de herramientas que nos ayudan durante el proceso y hacen que nuestras decisiones sean más consecuentes y meditadas. Pasaremos a divertirnos con ese código que al principio nos daba tanta pereza. Invertir tiempo en tener una buena caja de herramientas en mi opinión es una buena decisión de cara al futuro. Técnicas como estas no caducan, no son como la última librería JS o la versión 8.3 del framework de turno.

¿Qué técnicas conoces? ¿Cuál añadirías? ¿Cuál de estas has usado y te ha servido? mejor aún, ¿Cuál has usado y no te sirvió?¿Por qué?

Modernizando aplicaciones PHP: antipatrones más comunes

A lo largo de mi carrera he tenido la oportunidad de “meter las narices” en unas cuantas aplicaciones… a algunas de ese aplicaciones podríamos llamarlas “legacy” en el sentido de que son aplicaciones que necesitan algo de “cariño”. Recuerdo una pregunta en una ¿Y tu cómo te enfrentas a aplicaciones legacy? mi respuesta fue Con paciencia. Así que hoy escribiremos sobre antipatrones más comunes cuando nos enfrentamos a una aplicación legacy. Este artículo no vamos a reescribir todo en <el fancy framwork que sea>,sino que veremos como hacer nuestras aplicaciones un poco más mantenibles.

Si quieres profundizar más sobre el legacy este artículo titulado “Mi código en producción ya es legacy” de Fran Iglesias es genial.

Sigue leyendo “Modernizando aplicaciones PHP: antipatrones más comunes”

Charlas interesantes durante el confinamiento

En estos días de estar en casa, me ha dado tiempo a ver/escuchar algunas charlar interesantes sobre todo mientras estoy haciendo mi deporte favorito de cuarentena: subir y bajar las escaleras.

Y los podcast que escucho asiduamente son:

Tengo pendiente de ver unas algunas, pero me pica la curiosidad el canal de Carlos Ble porque últimamente está subiendo videos con Live Conding https://www.youtube.com/user/carlosble/videos 

Productividad: Email, calendario, notificaciones, tiempo…

En estos días de COVID-19, de teletrabajo y de una realidad un tanto incierta voy a hablar un poco sobre productividad. Estos días de confinamiento he estado ojeando infinidad de post sobre teletrabajo, mantener la comunicación ahora que estamos confinados, sobre productividad,… y un largo etcétera de temas similares. Así que me he animado a contar como organizo mi día a día en el MundoReal™ y no solo en estos días de aislamiento.

Antes de continuar, todo lo que escribo en este post me aplica a mi y a mis circunstancias, mis sesgos,… quizás no sean extrapolables a las tuyas. Sólo cuento como me organizo por si alguien puede coger ideas.

Sigue leyendo “Productividad: Email, calendario, notificaciones, tiempo…”

Charlas interesantes 8 Marzo

Este post es una recopilación charlas sobre como mejorar como desarrolladores. En estas charlas nos cuentan consejos, experiencias,.. y al menos a mi me han ayudado a replantearme una serie de creencias para seguir aprendiendo y mejorando no solo como desarrollador sino también como persona.

Lead Dev: no tengo ni idea de qué es eso

¿Qué es un Tech Lead? ¿Qué es un Lead Dev?¿Engineering Manager? Todos son roles que una persona puede desempeñar dentro una compañía. Hasta hay vamos bien, el problema viene cuando tenemos que definir las responsabilidades de este rol…

En cada compañía se hace de una manera. Podemos encontrar compañías en la que el career path es público y por tanto conocer cuales son las responsabilidades y/o habilidades que se suponen para dicho rol. Por ejemplo tenemos Patreon Engineering Levels donde definen las habilidades y responsabilidades de cada nivel. También tenemos Medium Engineering Growth Rubric (más visual aquí) donde ponen incluso ponen ejemplos de cada lo que debería hacer una persona dentro de un nivel. Otro ejemplo más de Monzo. En mi caso, el Lead Dev se define como el CTO de un producto encargado de definir la visión técnica para alcanzar los objetivos de negocio establecidos por el Product Owner.  La cuestión es ¿qué pasa cuando te dicen: ‘¿te gustaría ser Lead Dev de este equipo?’ o lo más habitual… a partir de X eres el Lead Dev del equipo.

Sigue leyendo “Lead Dev: no tengo ni idea de qué es eso”

Desplegar en Heroku una App en Go

¡Volvemos a la carga! Esta vez con un post un poco más técnico que los últimos. Hace tiempo que llevo dandole vuelta a como mejorar la manera en la que desplegamos el software, sobre todo desde que vi la charla de “Deliveritis Aguda de Carlos Buenosvinos.

Así que me he puesto manos a la obra analizando como desplegamos nosotros y como automatizar al máximo posible el deploy. Después de ver distintas opciones la que más sencilla me ha parecido para proyectos personales es Heroku.

Crear cuenta en Heroku

Lo primero es crear una cuenta en Heroku. Tiene una capa gratuita que es suficiente para hacer pruebas.

01 cuenta heroku

Una vez que tengamos la cuenta lista, tenemos que instalar en nuestro ordenador Heroku CLI, en mi caso he optado por la instalación de brew

Sigue leyendo “Desplegar en Heroku una App en Go”

Charlas interesantes Enero 2020

Estas son algunas de las charlas que más me han gustado últimamente:

Muchas de ellas las he escuchado en podcast usando Ivoox (https://www.ivoox.com/en/escuchar-autentia_nq_340369_1.html) y otras en youtube done estoy suscrito a varios canales.

Espero que las disfrutéis

Retrospectiva y objetivos 2020

Aunque con un poco de retraso creo que es hora de echar la vista atrás y analizar todo lo que ha pasado este año. Si tuviera que resumir todo 2019 con una frase sería: se me ha pasado volando el año y creo que no me ha dado tiempo a hacer todo lo que me hubiese gustado.

Esa era la sensación que tenía cuando fui a escribir el post, luego me puse a buscar y recopilar información de todo lo que me había pasado este año… En realidad, ha sido un año en el cual he ido priorizando a medida que iba avanzando el año, por lo que no he cumplido los objetivos que me propuse al principio, pero no me importa he hecho otras cosas que me han molado más.

Sigue leyendo “Retrospectiva y objetivos 2020”

Trabajando en remoto

Remoto, teletrabajo, trabajar desde casa, trabajar desde cualquier sitio… es el concepto de moda entre todos los programadores que conozco. Llevo un tiempo trabajando desde casa y en este post voy a contar algunos consejos que me han funcionado (y otros que no) en más de un año fuera de la oficina.

Lo primero puntualizar un poco. Cuando hablamos de remoto, nos podemos estar refiriendo a un amplio abanico de posibilidades, es decir, según como yo lo veo hay distintos tipos de remoto:

Sigue leyendo “Trabajando en remoto”