De todas las creencias del ideario informático, una de las que más me duele cuando la escucho es la archiconocida:

Lo puedo hacer rápido o lo puedo hacer bien

con una de sus variantes estrella:

Esta feature son dos días, pero con test cuatro

a lo que muchas veces desde producto nos contestan:

¿pero cómo tardas tanto? (si eso es poner un if)

y eso ya hace que nos hierva la sangre imposibilitando la conversación…

Con este post pretendo exponer que, desde mi punto de vista, la calidad y la velocidad no están reñidas en el desarrollo software. Sino más bien al contrario. Para ello voy a intentar desgranar los tres conceptos importantes de los que habla la primera frase.

Rápido

Cuéntame la versión larga, please :).

Mi primera reflexión va sobre el concepto de rápido. ¡¡¡Siempre tenemos prisa!!!. Yo creo que para poder tener una conversación razonable con la parte que nos mete prisa es importante entender el origen de esa prisa que puede ser por múltiples razones, a menudo por más de una a la vez:

  • Tenemos una ventana de tiempo muy ajustada y sí no salimos pronto, perdemos la oportunidad: Este es un caso legítimo, pero debería ser poco habitual. En mi opinión, si nuestro negocio siempre tiene esa urgencia por salir y sus ventanas de tiempo son ajustadas, estamos condenados a fracasar. Y deberíamos plantearnos otro tipo de soluciones.

  • Queremos minimizar la Ley de Parkinson que dice que "el trabajo se expande hasta llenar el tiempo disponible para que se termine": nos guste o no, esto es un problema real, aunque ahora lo llamamos procrastinar que suena como más gracioso. En cierto modo tiene sentido, que las personas encargadas del producto traten de reducir ese tiempo para evitar dilatar la tarea más de lo necesario. Y creo que a muchos nos viene bien que se haga un poco. Pero siempre con sentido común. He visto varias veces imponer fechas arbitrarias cuando luego no hacía falta tanta urgencia y veo el daño que hace a los ánimos del equipo y al software que se construye.

  • Me viene a la cabeza un caso también bastante típico en el que es el propio equipo de desarrollo quien tiene esa sensación de urgencia. A menudo porque la tarea que está haciendo nos aburre y otras veces porque directamente estamos en "modo deportivo".

    • ¿A quién no le ha pasado eso de estar dando vueltas sobre una tarea porque no estaba clara? Cuando pasa eso, no es raro escuchar frases del estilo de "luego no me vengáis con prisa". Hemos normalizado que el equipo de desarrollo se equivoque y haga ñapas casi por sistema, sin embargo toleramos poco las equivocaciones desde producto.
    • También recuerdo un caso concreto en el que yo era el responsable del equipo y tenía interés en que el resto del equipo aprendiera a refactorizar y aprendiera a añadir test al código legacy. Llevaban más de un año sin sacar funcionalidades nuevas porque el código estaba tan enrevesado que no podían. A pesar de eso el equipo me respondía: "Es que así vamos a ir muy lento". ¿Quién os mete prisa? Si yo soy el responsable de la agenda y os digo que tenemos tiempo ¿por qué tanta urgencia?..
  • Pero, para mi, la razón principal es que el mayor coste de un proyecto de desarrollo es el tiempo de sus desarrolladores y por lo tanto, terminar la tarea cuanto antes, es la forma más inmediata y evidente de abaratar el coste.

Con esto quiero decir, que la mayoría de las veces, cuando alguien nos dice que quiere algo rápido, lo que nos quiere decir es que quiere algo lo más barato posible. Y si nosotros somos conscientes de esto es muy probable que empecemos a tener conversaciones mucho más provechosas con la otra parte sobre por qué hacer algo a priori más lento, puede llegar a ser más rápido y por lo tanto más barato. ¡Por fin estaremos hablando el mismo lenguaje!

Además rápido es un concepto que requiere contexto y depende de la tarea a llevar a cabo. Por ejemplo, terminar una carrera en 2 horas ¿es rápido o lento? Pues depende, si hablamos de los 100 metros lisos, es muchísimo, pero para una maratón implica superar el actual record mundial. Y ya no digamos si estamos hablando de una carrera universitaria…

Debemos tener claro que las cosas llevan su tiempo y hacer software es una tarea delicada y tediosa. No debemos subestimarla porque luego nos estallará en la cara.

TLDR;


Es importante entender que la mayoría de las veces, cuando se quieren las cosas rápido, no es porque haya una urgencia real. Lo que se quiere es abaratar el proceso de desarrollo ya que el coste principal del proyecto se debe al coste de las personas implicadas en el mismo. De este modo conoceremos la motivación de la persona que transmite urgencia para así poder tener una conversación más adecuada.

Por otro lado, lo más común es que haya cierta/bastante incertidumbre durante el desarrollo por lo que es muy difícil predecir el tiempo que tardaríamos con una alternativa u otra. Y sino somos capaces de saber cuál es el tiempo razonable de desarrollo, ¿cómo podríamos saber que significa rápido o lento?


Bien

Cuéntame la versión larga, please :).

Mi siguiente reflexión va sobre el significado de bien para nosotros y para el resto del equipo. No creo que haya un criterio único y permanente aunque sí que hay algunas cuestiones que parecen ser condición necesaria (pero no suficiente) para considerar algo como de calidad.

Lo primero que me llama la atención de la afirmación "lo puedo hacer rápido o lo puedo hacer bien" es que de primeras no consideremos rápido como parte de nuestro criterio de bien.

Sin entrar, de momento, en detalles técnicos, para mi una tarea está bien resuelta si:

  • Resuelve el problema que justifica llevar a cabo la tarea.
  • Perdura el tiempo que se espera de ella.
  • El coste de mantenimiento es razonable. Es decir, no se dispara en el tiempo.
  • Y por supuesto que esté hecha en el menor tiempo posible. O lo que es lo mismo… todo lo rápido que podamos.

Entrando en detalles técnicos, entiendo que cuando hablamos de hacer las cosas bien nos referimos a tener en cuenta todos esos criterios que la industria ha establecido como "de calidad", entre los que se encuentran:

  • Testing automático (incluso TDD)
  • Pull Requests
  • Continuous Integration/Delivery/Deployment
  • Micro servicios
  • RX
  • Clean architecture
  • Con feature flags
  • Con métricas de uso y rendimiento
  • (y cualquier otra buzzword que se nos ocurra)…

Es curioso, lo interiorizado que podemos llegar a tener, que todas estas prácticas que acabo de mencionar incrementan el tiempo de desarrollo, cuando todas ellas están pensadas precisamente para lo contrario.

Tenemos un prejuicio, heredado del mundo físico que nos dice que hacer las cosas bien es más lento y por lo tanto más caro que hacerlas mal y es algo que tenemos que dejar de lado cuanto antes para poder mejorar en nuestro trabajo.

Veo dos problemas claros aquí:

  1. No tenemos asimiladas estas técnicas y por lo tanto nos parecen más difíciles de lo que son.
  2. Elegimos mal la unidad de estudio.

    La decisión epistemológica más importante que se hace es la unidad de estudio. Si nos equivocamos en la elección de la unidad podemos encontrarnos enfrentando el organismo a su ambiente.
    (Gregory Bateson)

    Me explico. Si la unidad de estudio es la tarea a desarrollar, quizás, aplicar todas estas técnicas pueda introducir un sobrecoste.
    No obstante, las tareas rara vez se realizan de forma aislada, sino que se realizan en el contexto de un proyecto. En este caso, la unidad de estudio podría ser el proyecto, donde lo interesante es minimizar el impacto en la suma de todas sus tareas.

    En general el hecho de cambiar la unidad de estudio, nos hará cambiar de prioridades dándole más importancia a unas variables u otras a la hora de tomar la decisión. Es decir, decidiremos con inteligencia.

Y por úlitmo me gustaría resaltar que nuestra definición de bien cambia con el tiempo. Tanto nosotros como desarrolladores o equipo, como el proyecto y la empresa para la que trabajamos, nos comportamos como un ser vivo y por lo tanto cambiamos, maduramos y nuestras prioridades cambian y por lo tanto la definición de bien puede (y seguramente sea así) hacerlo también. Es importante tener esto en cuenta tanto a la hora de tomar una decisión, como a la hora de juzgar el pasado. Idealmente, deberíamos tener la conciencia tranquila pensando que en cada momento tomamos la decisión que creíamos que era mejor en el momento en el que tomamos la decisión y con el conocimiento que teníamos entonces. Juzgar en el presente, no solo es muy fácil, sino que suele ser bastante injusto.

TLDR;


No creo que haya un criterio fijo para determinar que algo está bien hecho. Es más, a menudo, nuestra definición de bien cambia con el tiempo. Sin embargo, deberíamos tratar de estar contentos con nuestras decisiones y nuestro trabajo.

Debemos conformarnos con hacer las cosas lo mejor que sepamos en el momento en que las hacemos y en las condiciones en que las hacemos. No obstante, es responsabilidad nuestra intentar negociar tanto con el alcance de la tarea como con el tiempo de la misma antes de decidir no hacer “las cosas bien”.


Hecho

Cuéntame la versión larga, please :).

Sin entrar en la famosa "definition of done", creo que es importante destacar aquí que nos movemos en el mundo de las ideas. Y por lo tanto tenemos una complicación adicional a cuando trabajamos de manera material.

Para empezar, muchas veces estamos haciendo algo que desconocemos por completo. Y otras tantas, lo que nos piden no es viable.

¿Alguien por estos lares vería razonable que os pidiera construir un puente desde Lisboa a New York? La cuestión es que me gusta mucho conducir y las vistas al mar me flipan así que me gustaría hacerme "la ruta transatlántica". Además como las vacaciones están cerca, me gustaría construir el puente en un mes, es que si nos pasamos de plazo ya no tiene sentido. ¿Quién se anima? Mirad que es una oportunidad única. !Y un reto super interesante! eso no lo ha hecho nadie y seguro que además nos forramos.

¿Os suena todo esto? Yo lo veo una y otra vez. Y muchas veces cuando se me ocurre decir, "eso es una locura, ni es viable, ni lo necesitas", me miran raro y/o mal. Por supuesto a veces me equivoco y por eso, aunque a veces me expreso mal y sueno tajante, intento ser razonable y estar dispuesto a sorprenderme y a comerme mis palabras por si resulta que la cosa no era tan complicada como pensaba.

Relacionando el concepto de hecho con el de rápido, o mejor dicho con el coste, creo que es interesante pararse a pensar las consecuencias de hacer o no hacer las cosas.

Muchas veces para llegar a tiempo, decidimos implementar únicamente el golden path asumiendo que todo es maravilloso y que las cosas irán siempre bien (cosa que luego nunca pasa). Al final hemos reducido el coste de desarrollo considerablemente a costa de incrementar el coste de mantenimiento más de lo necesario. Por eso debemos tener siempre en cuenta que:

coste de feature = desarrollo + mantenimiento + oportunidad

Cuando hablo de coste, no me refiero solo a monedas. Sino también a bienestar personal, armonía en el día a día y cualquier valor tangible o intangible, a la capacidad de seguir desarrollando ideas a una velocidad aceptable… Sabiendo esto, podremos tomar una decisión mucho mejor. En general me atrevería a decir que habitualmente no tendremos que llegar a la perfección casi nunca, pero tampoco deberíamos abusar de las ñapas.

Por último me gustaría dedicar unas líneas para pensar qué hace que una tarea nos consuma tiempo:

  1. Burocracia
  2. Comprender el problema
  3. Pensar su solución
  4. Llevarla a cabo
  5. Probarla

La cuestión es que para mi los puntos 2 y 3 son los más importantes con diferencia. En general, es en el momento de comprender el problema cuando tratamos de razonarlo y simplificarlo de manera que la solución sea evidente y llevarlo a cabo (el punto 4) sea una tarea relativamente sencilla.

En el momento de pensar es cuando asimilamos los conceptos del negocio que estamos modelando y adquirimos/definimos el vocabulario de negocio que luego será común entre producto, desarrollo y nuestro código.

El problema de todo esto, es que tanto los profanos como, en ocasiones, las personas encargadas del desarrollo, pueden considerar todo ese conocimiento como algo intangible y solo al desarrollarlo se considera que se está trabajando. Si no tenemos algo físico, no vemos el valor adquirido. La consecuencia de este proceder que tenemos tan arraigado, es que cuando tenemos ese sentimiento de urgencia, de lo primero que prescindimos es de lo más importante: de pensar (puntos 2 y 3) y de probar. Al final acabamos con algo tangible, pero que hace aguas por todos lados y que nos da unos dolores de cabeza importantes. Pero no pasa nada, lo llamamos deuda técnica y se acabó el problema. Como le hemos puesto un nombre elegante, podemos seguir pa’lante como si nada porque esto ya es un problema a medio/largo plazo y por lo tanto del futuro yo :P. Pero lo que debemos tener claro aquí, es que al ritmo al que nos movemos, el medio plazo en un proyecto software viene a ser en un mes y medio :S.

TLDR;


Nos movemos en el mundo de las ideas y por lo tanto, no nos regimos por las limitaciones físicas. Esto hace que se nos planteen ideas que o bien son bastante laxas o bien no son viables. Además, es posible que la idea que nos comentan se pueda llevar a cabo en varias fases sin necesidad de implementarla entera. No olvidemos, que la mayoría de las veces podemos plantear el proceso de desarrollo como iterativo e incremental por lo tanto es buena práctica comprender cuál es la parte imprescindible de la tarea y de cuál podemos prescindir en una primera versión.


Conclusiones

  • Pues en mi opinión, como con cualquier sistema que pretendamos perpetuar, no debemos maximizar una variable en detrimento de las demás, ya que si no, el sistema acaba volviéndose insostenible. No apliquemos la misma formula a cada caso. Cada tarea forma parte de un conjunto mayor y juega un papel más o menos relevante en el mismo. No tienen por qué aplicar los mismos principios a una feature que vivirá un día o una semana, que una que sea core de nuestra aplicación.

  • La mayoría de las veces, hacer las cosas bien, no es ni más lento ni más difícil que hacerlas mal. Es simplemente que no sabemos hacerlas y por lo tanto necesitamos dedicar tiempo a aprender. Cuando no tenemos el hábito de estudiar, atribuimos mucha incertidumbre al hecho de buscar y aprender a hacer las cosas, creo que es por ello por lo que asumimos que hacerlas bien va a ser lento. Sin embargo, ¿cuánto tiempo nos puede ahorrar el hecho de aprender algo en nuestro proyecto actual?¿y en los futuros proyectos?

  • Por último, intentemos comprender el origen de esa prisa y tratemos de negociar con el alcance de la tarea. Tengamos muy presente el aspecto de desarrollo incremental que nos permite el desarrollo software frente a el mundo físico.