En mi opinión, el código está bien hecho si puede ser entendido por un programador tan rápido como este es capaz de leerlo. Si se tiene que parar a pensar, entonces el código tal vez NO esté bien hecho. Está bien hecho si Product Owner, experto en el dominio, lo puede comprender con apenas algunas explicaciones del técnico que se lo está contando.
El código es bueno si no causa problemas de mantenimiento. Esto es: si cuando se produce un bug, se encuentra y se arregla rápidamente (cuestion de segundos o pocos minutos) entonces esta bien hecho. Incluso aunque hemos detectado algún bug (defecto) en el código, esto no significa que sea malo. Puede ser bueno si hemos comprendido y arreglado rápida y sencillamente el problema, ya que código bien hecho no es código perfecto. Un humano no es perfecto y por tanto no puede escribir código perfecto. El artesano escribe buen código.
Aunque estas afirmaciones pueden parecer exageradas o incluso utópicas, la experiencia me va demostrando cada vez más, que todo lo que se aleja de estas bases causa problemas a medio y largo plazo. Cada vez que hemos querido “correr” para poner en producción una nueva funcionalidad y nos hemos saltado a la torera TDD, lo hemos pagado con bugs en producción y código frágil. Afortunadamente no han sido muchas las veces pero lo cuento para insistir que incluso nosotros, que creemos tanto en TDD, a veces nos lo hemos saltado. Y justamente cuando hemos dicho…. “ok, vamos a sacar esta funcionalidad sin hacer TDD y la vamos a tener corriengo para mañana y luego ya refactorizamos. Además la haré yo solo a toda leche y tu haces tal y cual otra cosa mientras”, es cuando hemos tenido mil problemas. Por un lado bugs que han llegado a producción, con la consecuente mala experiencia para el usuario. Por otro lado código difícil de mantener. Cuando lo hemos tenido que depurar, hemos tardado tanto en encontrar los fallos y comprenderlos como lo que habiamos tardado en escribir ese código. Llegado ese punto ya estabamos perdiendo dinero. Cuando hemos querido refactorizar el código prácticamente hemos tenido que borrarlo entero y volverlo a hacer. Curiosamente, al rediseñarlo con TDD hemos incluso descubierto más casos no planeados que iban camino de ser tediosos bugs en producción. Está clarísimo que nos ha salido siempre mucho más caro querer correr y reparchear que hacer las cosas de la mejor forma posible desde un inicio.
Otro error que hemos cometido a veces, es usar el código de un spike para producción. Un spike es la típica prueba que haces para comprender cómo funciona una nueva herramienta o API. Por ejemplo nos ha pasado en la integracion con APIs como Twitter o Google Maps. Teníamos que consumir una libreria de terceros sin saber muy bien como funcionaba. Al no conocer el comportamiento no podemos hacer TDD ya que no sabríamos como especificar el comportamiento de un mock o un stub. Entonces te lanzas y haces el spike. Hasta aquí todo bien. El error viene cuando el spike parece funcionar y entonces lo pruebas un poco a mano y lo subes a producción. Esto nos ha causado los mismos problemas que comentaba antes. Ahora cada vez que hacemos un spike, comprendemos el problema y entonces podemos diseñar cuidadosamente (con especificaciones como siempre) y estar seguros de que cada bloque que escribimos hace lo que tiene que hacer.
Siempre que nos hemos saltado el principio de responsabilidad única (SRP) lo hemos pagado. Especialmente cuando en el código del controlador acabamos poniendo reglas de negocio. En un principio nos lo permitimos porque estas reglas son validaciones del input del usuario pero…. es que al final esas validaciones son muy importantes!!! Nuestra arquitectura ideal en la web es la que comentaba en un post anterior. Cada vez que el controlador contiene más negocio del que debiera (y debiera tener cero negocio) encontramos problemas de mantenimiento.
Cuando uno se sienta a escribir código, no puede tener prisa. Debe tener concentración. Prisa y concentración son dificiles de conseguir a la vez. Lo más probable es que se produzca ansiedad en tal caso. La falsa sensación de que puedes ir rápido y escribir buen código es una fuente de problemas. Las cosas bien hechas no se pueden llevar a cabo en dos dias. Esto de llegar un fin de semana, sentarse 2 amigos y hacer una aplicación, no puede producir código bien hecho. Puede estar bien como prototipo, para mostrar una idea, pero desde luego no es código que yo quiera mantener ni evolucionar.
El hecho de invertir mi propio dinero en mis desarrollos ha sido lo que me ha llevado a querer pisar el acelerador en algunos casos, algo que sucede a muchos dueños de producto. Sin embargo, en términos monetarios, hemos salido perdiendo siempre que hemos hecho esto.
Por otra parte, uno no se puede sentar a escribir código y estar entretenido con un método eternamente hasta que le parece el mejor código del mundo. El trabajo del artesano debe ser fluido, sin prisa pero sin pausa. Con atención al trabajo pero sin perseguir la perfección. No hay que detenerse a hacer refactoring hasta la saciedad. A veces uno escribe código que sabe que no es el mejor, pero en ese momento no tiene la lucidez para mejorarlo. La experiencia te muestra tus propias limitaciones y debes aceptarlas. Aceptarlas significa que en algún lugar anotarás que quieres mejorar ese código y que tan pronto como te sea posible lo harás, seguramente desde que añadas un poco más de funcionalidad a ese bloque. Y “tan pronto como sea posible” será literalmente verdad.
Ser artesano implica ser disciplinado. Pero nadie puede ser disclinado durante 40 horas a la semana, todas las semanas durante 11 meses al año. Con esto voy a que no se puede escribir código bueno cuando se trabaja demasiadas horas. Personalmente encuentro que a partir de las 6 horas, la calidad de mi código disminuye y mi interes por ello también. Nunca compraría código de una empresa que tiene a sus empleados trabajando 10 horas al día, como ocurre en tantas empresas que conozco.
Conforme adquiero experiencia, me doy cuenta de que las demás practicas de XP, son tan importantes como TDD. Programar en pareja, revisar el código de los demás, integrar frecuentemente… Estoy empezando a pensar que las empresas en que nunca se hace programación en pareja, no tienen la madurez suficiente para hacer buenos productos software. Bueno, yo al menos no pagaría por ellos.
Kent Beck, Robert Martin, Martin Fowler, Steve Freeman y tantos otros profesionales, no nos están contando mentiras para vender libros. No están exagerando. Esta es mi impresión sobre el desarrollo de software, cada vez más.
Cada cual es libre de escribir el código como quiera, sobre todo si es open source, pero que nadie se engañe… ningún programador es perfecto. ¿y tu? ¿eres artesano? 🙂