¿Está mi código bien hecho?

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? 🙂

Enjoyed reading this post?
Subscribe to the RSS feed and have all new posts delivered straight to you.
  • Pingback: ¿Está mi código bien hecho?()

  • Guillermo

    Totalmente de acuerdo. Gran post!

  • http://www.etnassoft.com EtnasSoft

    Efectivamente, el código solo es bueno cuando puede ser entendido de un simple vistazo.

    Ese es el objetivo por ejemplo de la refactorización que Fowles y Beck proponen: si un código precisa de comentarios para ser entendido, es probable que haya que revisarlo hasta que cualquier comentario parezca superfluo.

    La programación basada en TDD es una excelente aproximación al código legible ya que facilita la refactorización.

    Buen artículo.

  • Jorge Rowies

    Muy buen post, se agradece el aporte

  • Pingback: Sobre artesanos y cowboys | Blog de Rodrigo Juarez()

  • Dario

    Poner un sitio en produccion lo antes posible aunque no tenga TDD, aunque tenga horripilantes bugs, permite ganar comercialmente, ya que el usuario nunca tendra la capacidad de juzgar al codigo.
    Y sepan que soy partidario de hacer las cosas bien desde el inicio (uso TDD para todo, SCV bien ordenado desde el comienzo del proyecto, refactorizo frecuentemente y trato de diseñar bien el soft, etc…), pero esto solo se puede aplicar bien en el software libre, por ejemplo.

    En el contexto del soft. a medida, la prioridad siempre sera ganarse al cliente/usuario, y eso implica poner a la aplicacion en produccion lo mas rapido posible mas alla de cuantos bugs tenga o problemas de escalabilidad o cualquier cosa que puede dar problemas en el “futuro” que solo llegara si se gana comercialmente AHORA… lo que digo es que no sirve de nada crear tests, refactorizar el codigo o diseñar algo muy flexible si eso se hace para un futuro que no llegara por que no se puso la aplicacion en produccion cuando el cliente demandaba.

    En proyectos de la facultad tambien se obvian esas practicas, ya que existe un deadline para entregar algo funcional, pero que rerpesenta el fin del proyecto y todos los artefactos desarrollados y el source se descartan, no hay futuro mas alla de ese deadline. Sin embargo practicas como el unit testing (no conocia TDD en ese momento) realmente fueron las que me salvaron en un TP, cuando lo que desarrollabamos no toleraba errores en cierto componente que ademas tenia un grado de testeabilidad muy alto

    En contextos como el software libre, no tengo deadlines, entonces utilizo las mejores practicas que conozco, precisamente estoy desarrollando en ruby y recientemente me estoy metiendo con RSpec y todas sus ventajas con el mocking, etc…. Mi codigo “se ve un poco mejor” cuando es libre, ya que se que hay “millones” de ojos mirando. Respecto a los deadlines, creo que si tuviera deadlines o por lo menos objetivos mas funcionales definidos, creo que desarrollaria mas productivamente (y el codigo seria un poco ms feo).

  • http://1poquitodtodo@blogspot.com Juan Quijano

    Casi totálmente de acuerdo contigo. Solamente en dos cosas no lo estoy:

    1. Se ha echo grandísimo software sin XP, sin Agile, sin TDD y ni tan siquiera POO. Ayudar, ayuda, pero no son lo que hacen la calidad. La calidad se consigue con el talento del equipo.

    2. TDD no es una bala de plata… ni muchísimo menos. Es un acto de fé que, a mí personalmente, sigue sin gustarme. Las aplicaciones de software son lo suficientemente complejas como para que querer construir un bosque mirando las hojas, no tenga sentido. Pero bueno es solo una opinión.

    Muchas gracias por compartir tus experiencias. En mi contexto intento no ir con prisas, pero ellas siempre me alcanzan.

  • http://carlosble.com Carlos Ble

    Yo no he dicho que con TDD se vaya mas lento. Al contrario, he venido a decir que somos mas rapidos en el medio y largo plazo. Lo que comenta Dario esta bien si la aplicacion no va a ser mantenida. Pero si hay que mantenerla, yo sin duda prefiero hacerla bien. Hacer TDD, definitivamente NO es mas lento, (en nuestro caso) sino que exige tener claro lo que se pretende, lo cual es bueno para el negocio.

    Sobre lo que comenta Juan, decir que a mi me vale el codigo si no esta hecho con TDD pero igualmente cumple principios como SOLID. Si es claro, si es bueno, me da igual como este hecho. Aunque hoy en dia tambien exigiria que tuviese una buena bateria de tests automaticos, pero me daria igual que se hubiesen escrito a posteriori. Asi que TDD no es la solucion universal, pero para humanos con un intelecto corriente como el mio, ayuda muchisimo a escribir buen codigo. No dudo que otras personas con mayor capacidad intelectual que la mia puedan escribir codigo de la misma calidad que el que yo pueda escribir con TDD, sin TDD. Solo me defiendo contra mi mismo 🙂

    Gracias por vuestras aportaciones

  • Pingback: 4 versiones de la kata Fizz Buzz | Yo y el software()

  • http://elmundoexterior.es alexito4

    Un gran post!
    Des de mi corta experiencia tengo que decir que estoy totalmente de acuerdo contigo 🙂

    Salu2

  • http://category=PluckPersona&U=aa51fd3c8b6d4ec5b4220d6ae4cb67b3&plckPersonaPage=BlogViewPost&plckUserId=aa51fd3 Ashley Padavich

    Hello, Neat post. There is an issue along with your web site in web explorer, would check this… IE still is the market leader and a good component to other folks will pass over your magnificent writing due to this problem.

  • http://www.kursy-angielski-warszawa.com.pl/zajecia-przeznaczone-dla-mlodziezy-szkolne Kursy angielskiego Warszawa

    I always was concerned in this topic and still am, thankyou for posting .