leanmind logo leanmind text logo

Artículos

Por Carlos Bléel 07/07/2019

La simplicidad por principio

Caracola

Escribir código simple es tremendamente complicado. La virtud de encontrar la simplicidad es la clave del éxito de los proyectos ágiles. Pero estamos entrenados para la complejidad, vemos más complejidad de la que realmente hay y hacemos las cosas más difíciles de lo que son. Nos enorgullecemos de crear complejidad como si fuera algo grandioso. La complejidad accidental es la principal causa de problemas a la hora de mantener el código.

Toda esa complejidad introducida que es innecesaria para el éxito del proyecto, se llama complejidad accidental.

Hace años el gran programdor Kent Beck inventó las 4 reglas del diseño simple:

Si el código no tiene tests automáticos, estamos ante un grave problema de mantenimiento. Cuanto más corras escribiendo nuevas líneas de código sin tests, más cuesta arriba se hará la continuidad del proyecto. Crees que ganas ventaja pero en realidad te alejas de hacer código simple, estas disparando el coste de mantenimiento del producto. Cada vez dedicas más tiempo de tu día a depurar: breakpoints, console prints, pruebas manuales de la aplicación… Los tests te ayudan a simplificar porque te hacen pensar sobre el código que escribes. El cuello de botella del proyecto nunca ha sido pensar, sino la complejidad accidental.

La forma de conseguir encontrar el tiempo para escribir los tests que te faltan es dejando de escribir las líneas de código que no tienes que meter en el proyecto, las que aumentan su complejidad accidental. ¿Puedes hacer lo mismo sin esa herencia? ¿y sin esa inyección de dependencias? ¿puedes hacerlo con menos líneas? ¿con menos clases? ¿con menos métodos? ¿con menos variables? ¿con menos bucles? ¿con menos condicionales? ¿con menos mocks? …

J.B Rainsberger cuenta muy bien en 7 minutos su teorema fundamental de la agilidad:

Un software que realiza tareas sencillas, debería tener un código simple. ¿Tu aplicación está controlando una misión espacial? Si la respuesta es no, entonces ¿por qué es tan difícil entender y cambiar su código? La respuesta es que los programadores introdujeron más complejidad de la necesaria.

A menudo el conflicto entre managers y programadores surge porque los primeros no entienden como un producto sencillo puede ser tan difícil de cambiar. Y los segundos a menudo no se dan cuenta que podían haber programado algo más simple. Es más fácil verlo cuando son otros los que lo programaron y ya no están. Entonces se dice que los programadores anteriores lo hicieron fatal, hicieron un código spaguetti sin tests y ahora no lo podemos mantener. A veces los unos y los otros se ponen de acuerdo para volverlo a escribir desde cero y todo el mundo está contento hasta que unos meses despúes los programadores vuelven a quejarse de que el código es un infierno. Albert Einstein decía que es de tontos repetir el mismo experimento buscando resultados diferentes.

El secreto para ir rápido en los proyectos, para ser ágiles de verdad, es reducir al máximo la complejidad del software. Escribir la menor cantidad de líneas de código posible. Con la menor complejidad ciclomática posible. Con la menor cantidad de indirección posible y de abstracciones. “Clean code” no consiste en hacer métodos de cuatro líneas por todo el código sin cohesión, abstracciones artificiales con nombre alienígenas. Consiste en las cuatro reglas del diseño simple. En adecuar el código al contexto del problema, de la finalidad de la herramienta que estamos construyendo.

Esto me recuerda al díalogo entre John Connor y el T-1000:

J.Connor: Wait a minute here. You're telling me that this thing can imitate 
          anything it touches?
The Terminator: Anything it samples by physical contact.
J. Connor : Get real, like it could disguise itself as a pack of cigarettes?
The Terminator: No, only an object of equal size.
J.Connor: Then why doesn't it become a bomb or a machine gun or something 
          to get me?
The Terminator: The T-1000 can't form complex machines. Guns and explosives 
                have chemicals in them. Moving parts. It doesn't work that 
                way, but it can form solid metal shapes.
John Connor : Like what?
The Terminator : Knives and stabbing weapons

No construyas bombas atómicas cuando lo que te están pidiendo es una caja de cerillas. Tírate al suelo y haz 10 flexiones cada vez que se te pase por la cabeza añadir algo al código “por si acaso”.

Si construyes código para startups debes saber que, la gran mayoría fracasa, cierran antes de los tres años.
Tienes muy pocas probabilidades de que tu código se use en realidad así que olvídate de escribir código reusable y prioriza el time to market para que llegue a ser usado alguna vez. Incluso en empresas que no son startups es poco probable que tu software acabe usándose durante años.

Olvídate de escalabilidad, de microservicios, de kubernetes. Olvídate de agregados, de event sourcing, de herencias y frameworks ad hoc. Escribe el código más simple que puedas, en el menor tiempo posible, con los mejores tests que sepas escribir. Haz un código que sea fácil de cambiar para pivotar tan rápido como el negocio lo necesite. Justfica bien por qué quieres empezar el proyecto con un repositorio de Git para el backend, otro para el frontend, otro para … ¿es porque lo hace alguna otra empresa? ¿y qué? ¿por qué lo hacen ellos? ¿nosotros tenemos las mismas necesidades? Pon en una balanza lo que pierdes y lo que ganas. Ten en cuenta que el software es evolutivo.

No significa que quizás en el futuro sea necesario llegar a esos niveles de complejidad, si el uso lo requiere se hace, pero no lo hacemos por si acaso. No como punto de partida. El uso del software en producción por usuarios reales durante meses es lo que debe marcar el rumbo de los cambios de infraestructura y la complejidad en general. Si el software no se usa, si no genera ningún bien, no sirve para nada. A menudo copiamos infraestructura y sistemas de grandes compañias de éxito como Netflix o Amazon olvidándonos de que su contexto es muy diferente al nuestro. Seguro que ellos cuando empezaban no tenían el sistema montado así, lo fueron adaptando a sus necesidades. La gracia de la agilidad es evolucionar conforme las necesidades lo demandan.

Esta habilidad es realmente difícil de desarrollar y define en parte de lo que considero seniority. Siente el orgullo de escribir código simple, código fácil de leer que se comporta como otro lector interpreta que lo hace.

¿Quieres más? te invitamos a suscribirte a nuestro boletín para avisarte cada vez que recopilemos contenido de calidad que compartir.

Si disfrutas leyendo nuestro blog, ¿imaginas lo divertido que sería trabajar con nosotros? ¿te gustaría?