El que muere paga todas sus deudas

Toma título lapidario, de la pluma del más funesto William Shakespeare nada menos. Que no se disparen todavía las alarmas, no va a tratar el post sobre la muerte de nadie, faltaría más. Pero sí sobre un factor que puede acelerar el fracaso de un proyecto tecnológico. Un fenómeno que toda acometida técnica de cierto calado va a enfrentar tarde o temprano. La crisis económica de los geeks de a pelo, su fin de ciclo particular. En fin, hablamos de la deuda técnica. Para los no puestos en el tema, la palabra “deuda” ha de ser indicativa de que no es éste un asunto baladí. Vaya si no lo es…

¡Palabras, palabras, todo palabras!

Te has embarcado en un nuevo proyecto de desarrollo. Una startup, o un nuevo producto/servicio en tu actual empresa, ambos sirven. Aquí todos somos buenos profesionales, ingenieros de carrera, así que el asunto se empieza por los cimientos: con la fase de diseño. Junto a la gente de producto se han definido unas características para el nuevo retoño, y ahora toca esbozar el esqueleto sobre el que se dará forma final al, hasta ahora, efímero concepto. Arquitectura, diagramas, componentes, escalabilidad, patrones, protocolos y demás frikadas. En fin, el business plan de los desarrolladores, para entendernos.

De hecho, la comparación entre el diseño de una aplicación y un business plan tiene mucho de acertada. Ambos son concisas hojas de ruta, ambos son ejercicios entrañables de wishful thinking, y ambos suelen reventar en 1000 pedazos al primer choque con la realidad. Esto es así. Mucha ingeniería, mucho UML y mucha zarandaja, pero el diseño original de un software tiende a quedarse obsoleto bien rápido. Y lo peor, a limitar la evolución del mismo. A la que empiecen a aflorar nuevas características y necesidades desconocidas durante la fase de diseño, éste se quedará bien corto, y tocará empezar a salirse de la pulcra línea de trabajo que nos habíamos marcado.

En ese ejercicio de creatividad forzosa será inevitable introducir en el software una serie de elementos no contemplados en el diseño inicial, poco acordes con su pulcro espíritu original: las chapuzas. Los tiempos apremian, el mercado no perdona y uno va cediendo al “bueno, como hay prisa lo hago así, que NO es la manera y está MAL, pero en cuanto tenga un rato lo arreglo…”. Y ya está, acabamos de contraer una pequeña (o no tan pequeña) deuda técnica. Cada vez que cedemos en calidad del software para cumplir con otras prioridades, sumamos deuda técnica. Cada vez que tomamos el atajo porque el camino correcto conlleva demasiado esfuerzo, cavamos un poquito más profunda nuestra propia tumba.

Cuando llega la desgracia, nunca viene sola, sino a batallones.

Entonces, ¿dónde radica realmente el problema? Al fin y al cabo, que las cosas no se hagan de la mejor manera posible en cada ocasión es algo previsible y realista. Una característica que no pase del “bien” y que esté lista en una semana puede ser más interesante que su versión “excelente” y que nos lleve más de un mes. Al menos desde un punto de vista de estrategia y negocio, claro. ¿Que no es perfecto? Mientras sea usable, me vale. Pero el problema es más profundo, y no se limita a esa característica coja en concreto. El problema real nace de la naturaleza iterativa del desarrollo de software. El problema es el del castillo de naipes.

Si alguna vez te has entretenido construyendo un castillo de naipes, te habrás dado cuenta bien rápido de su característica estructural básica. Y es que la probabilidad de éxito al construir un nuevo nivel depende más de lo sólidos que sean los niveles inferiores que de tu habilidad. Haz un mal primer piso deprisa y corriendo, poco asentado, y quizás llegues a levantar un segundo piso, pero del tercero seguro que no pasas. Se acumulan y suman las deficiencias con cada nuevo nivel, haciendo más difícil la edificación de uno posterior. Limitamos nuestra capacidad de acción con cada sacrificio estructural. Y el resultado, de un impacto visual innegable, es el derrumbamiento inevitable del castillo.

Pues con el software, igual. Con cada sacrificio que se hace, se suman deficiencias estructurales que van a ralentizar, limitar, o incluso impedir el añadido de nuevas funcionalidades. Cuando el mercado exija esas características, nos encontraremos ante una disyuntiva. O dedicar mucho más tiempo del aconsejable en adaptar el producto para permitirla, o asumir que no es posible implementarla en el estado actual del software. En cualquier caso, un freno a la sana evolución del proyecto. Y, de tirar por la calle del medio e implementarla mal, pervirtiendo aún más el diseño, limitaremos todavía más nuestra capacidad de acción posterior. Si no se paga la deuda técnica, llega un momento en que te acaban embargando.

Ser o no ser. Esa es la pregunta.

¿Nos centramos entonces en reciclar nuestro diseño a cada paso, en dedicar cuanto tiempo sea necesario a asegurar la buena forma del software? ¿Frenar, amoldar el ritmo de crecimiento del proyecto a nuestra capacidad para mantener la base de código siempre impoluta? Eso puede tener sentido en proyectos sin presión de mercado, donde la ventana de oportunidad no es un limitante. Software libre o side-projects, por ejemplo, se pueden centrar en la corrección antes que en el time-to-market. ¿En una startup? No lo creo. Para cuando re-escribas tu aplicación por tercera vez, mejor que nunca, tus competidores se habrán convertido en el único actor de tu mercado. Game over.

Hay algo que los perfiles técnicos tenemos dificultad para asumir cuando fundamos negocios. Y es que un negocio no vive de la pureza teórica de tu diseño, ni de la pulcritud y claridad de tu implementación. Un negocio vive de hacer negocio. Ni más, ni menos. La prioridad es siempre vender, conseguir usuarios, clientes, que tu servicio se use. Que sea rentable para poder seguir. El mejor software del mundo matará a tu empresa igual que el peor si no tiene salida comercial. Sin más. Y entonces… si no combatir la deuda técnica puede matarme, pero centrarme en combatirla puede matarme…. ¿qué me queda? Pues queda pactar.

No sé vosotros, pero yo he vivido en la mayoría de empresas donde he trabajado una clara dicotomía negocio/desarrollo. El lado negocio quiere que el tiempo de desarrollo se centre en funcionalidades (son vendibles), y el lado desarrollo quiere centrar buena parte de ese tiempo en herramientas, mejoras, re-escrituras, y demás (mejoran la calidad). En la negociación de los ciclos de desarrollo, en mi experiencia, suele salirse con la suya negocio. Y es que, como comentaba antes, el fin último de una empresa es hacer negocio, y eso ha de primar. Lo que no he visto tan a menudo es que la mejora de la calidad acabe teniendo cabida en esos ciclos, con la consecuente contracción de deuda técnica.

Mi propuesta es sencilla. El producto manda, y los ciclos han de protagonizarlos, por lo general, las nuevas características vendibles. Pero la deuda técnica es un veneno para el producto, y el lado negocio ha de asumirlo sí o sí. Todo ciclo de desarrollo ha de incluir un pequeño porcentaje de tiempo (¿15%? ¿más? ¿menos? eso ya depende del ciclo y las necesidades puntuales en ese momento) dedicado a subsanar limitaciones técnicas. Las tareas puramente arquitecturales que se lleven a cabo han de definirse previamente, como con cualquier otra tarea del ciclo. Y ha de comunicarse a negocio cual es el riesgo que entraña no llevarlas a cabo: limitaciones futuras, horas malgastadas a causa de falta de herramientas, etc… En fin, dejar claro que esas horas no son una suerte de “recreo” de los técnicos, son tan esenciales en la vida del producto como el añadir nuevas características.

En una startup, donde los conceptos de negocio y desarrollo no están ni tan marcados ni tan enfrentados, es más fácil, claro. Suele haber más equilibrio de poderes, mejor entendimiento y más implicación de todas las partes en todas las facetas del producto. En nuestro caso, por ejemplo, Diego tiene suficiente base técnica para entender perfectamente cuán importante es gestionar esa deuda, y por qué. El riesgo en una startup viene un poco por el lado contrario en ocasiones. Preponderancia de fundadores técnicos que se pierden en un sinfín de re-escrituras y consideraciones estético-filosóficas sobre el código. Es igual de peligroso, si no más, ya que sufres el riesgo de morir antes de haber lanzado nada útil al mercado…

Antes que nada ser verídico para contigo mismo.

Y para muestra, un botón. Toda la teoría es muy bonita, pero suele encajar mejor si se acompaña de un ejemplo. Y por dar uno de primera mano, y porque en Ducksboard no nos avergonzamos de comentar nuestros errores, voy a ilustrar todo lo anterior con un episodio de deuda técnica doméstico. Para situaros, el frontend web de Ducksboard se desarrolló deprisa y corriendo, tras el backend de obtención de datos, para tener una beta lo antes posible. El hacer las cosas deprisa y corriendo tiene sus consecuencias, y en otro post ya detallé el esfuerzo extra que nos supuso arreglar la primera, y muy deficiente, versión. Pero quiero detenerme en un aspecto concreto del frontend que todavía hoy nos da problemas por un diseño inflexible: los widgets.

Un widget es cada uno de esos cuadraditos que muestran datos en el dashboard. El diseño original satisfacía las necesidades primigenias, claro. Esto es poder mostrar varias fuentes de datos prefijadas, cambiar título y colores y poco más. Al principio eran pocos widgets, y aunque cada uno implica ciertas nuevas filas en base de datos, algo de Javascript y un poco de CSS, no era un trabajo excesivo. Pasan los meses, y se van a añadiendo características. Los widgets tienen varios tamaños, las fuentes de datos ya no son prefijadas, la cantidad de visualizaciones se multiplica… Y surgen dos problemas. Por un lado, la cantidad de trabajo para crear un widget aumenta, porque son muchas más variables. Por otro, el diseño original de widget no soporta las nuevas características, así que se workaroundea duplicando tipos de widgets prefijados al no disponer de flexibilidad en el modelo existente.

Resultado, tardamos en crear un widget bastante más tiempo del que solíamos, y mucho más del que debiéramos. Desde un punto de vista de producto no es tan malo: el usuario no percibe la diferencia, funciona igual. Pero desde un punto de vista de desarrollo de producto tenemos un problema: perdemos muchas, muchas horas en hacer widgets (tenemos cientos, y no dejan de hacerse nuevos) que podrían dedicarse a añadir y mejorar otras características. Un caso clásico de deuda técnica. No hay nada “roto” que impida comercializar el producto, pero una limitación de diseño nos está robando horas de manera poco tangible pero constante, y compromete el crecimiento posterior.

Lo he comentado antes, estoy muy a favor de priorizar las tareas con influencia directa en la comercialización del producto. Con una larga lista de nuevas características y productos y una planificación exigente, no era el momento de acometer cambios estructurales. Pero una vez capeado el chaparrón, y tras justificar la tarea con la gente de negocio, ya toca poner solución a un lastre que nos está robando tiempo y energías. El resultado será más tiempo que dedicar a lo realmente importante, menos fricción en el desarrollo (vamos, quemar menos a los técnicos) y más calidad final del producto. Un win-win en toda regla. Frenar un poco para correr más rápido después.

Morir, dormir… ¿dormir? Tal vez soñar.

En un mundo ideal sería posible anticipar todas las funcionalidades que un software vaya a integrar a lo largo de su ciclo vital. Quién sabe. En el mundo real, eso es prácticamente imposible, una quimera. El software es cambiante, se adapta a nuevas necesidades y cambia de foco. No hay diseño que soporte eso. Manteniendo eso en mente, hay que buscar un equilibrio entre dejar que tu proyecto se degrade tanto que se hunda bajo su propio peso, y aspirar a una perfección inasequible y estéril. La deuda técnica carcome el software a medida que crece, pero obsesionarse con ella puede crujirlo antes de empezar. Las cosas en su justa medida. La planificación es la clave.

Si te ha gustado, sígueme en @aitorciki dónde además hago chistes de PHP ;P

Advertisements

7 thoughts on “El que muere paga todas sus deudas

  1. Buen post! Yo, tanto cuando trabajaba de freelance como ahora que trabajo para una empresa, suelo reservar los viernes para mejorar el código del proyecto o aprender/explorar técnicas nuevas. Aunque ese tiempo se queda corto para grandes cambios a nivel de arquitectura, creo que ayuda bastante a que el proyecto no se vaya mucho de madre.

    1. Gracias :)

      Me gusta lo de reservar los viernes para esas tareas. Es visible, es previsible, y es difícil de olvidar. ¡Buena iniciativa!

    2. @happywebcoder Me gusta mucho la idea de dejar los viernes para refactorizar. Nosotros ahora mismo solemos hacer “parones” de cuándo en cuándo, que nos podemos permitir sobre todo cuándo somos nosotros mismo los que controlamos la hoja de ruta.

      Cuando el trabajo es para un cliente a veces hay que saber comunicarlo y hacerles ver la importancia. En la mayoría de las veces lo entienden sobre todo cuando les “avisas” del peligro que se corre de no refactorizar a tiempo para se cree la clásica bola de mierda que todos bien conocemos.

  2. Yo creo que el problema, en parte, viene dado por crear esa dicotomía entre negocio y desarrollo, y esa idea de que haces los planes y luego nada es como parece y toca cambiarlo todo.
    Yo quizá me paso de cínico y práctico, pero la segunda vez que te pasa, es por tonto. Si el desarrollo es cambio, entonces lo que hay que hacer es “abrazar el cambio”. Ir avanzando poco a poco sin separar en grandes fases el “wishful thinking” de la “toma de tierra”, estar preparado para poder hacer modificaciones sin que sea un trauma, adaptarse y modificar los métodos, herramientas y actitudes a esa realidad. Intentar enfrentarse al problema con el típico “primero averiguo las cosas, luego las hago, finalmente las entrego y las valido” es una receta para el desastre en la mayoría de ocasiones.

    ¿Y esto que tiene que ver con la “deuda técnica”? pues que si estás preparado y mentalizado para el cambio, las deudas no son tan gordas y más tarde cobrarlas no es tanto trauma. Que no existan nunca es misión imposible, pero si no estamos preparados para endeudarnos de una forma que nos convenga,

    Un ejemplo simple, en uno de los grupos donde yo trabajo, los cambios en “su producto”, que es una mega-aplicación monolítica se pasan a través de multiples niveles de gente, con incidencias en el gestor de tareas, únicamente a ciertas horas algunos días de la semana. Y como no sea por error grave, trás deliberaciones, planificaciones, etc. etc. Claro, cuando hacen una cagada, como le pasa a todo el mundo, si no es de vida o muerte se puede tirar ahí meses o años, hasta que la prioridad merece la pena para poner en marcha toda la “burocracia” de pasar cambios.

    Nosotros en cambio tenemos los servicios divididos en pequeñas aplicaciones, las actualizamos a cualquier hora en que no fastidiemos a los usuarios y no “tenemos miedo” por que hacer un “rollback” de un cambio en producción es tan sencillo como echar en el SVN de producción una versión para atrás. ¿Hacemos cagadas? De vez en cuando, como todo el mundo, pero la solución, echar para atrás, llega en minutos y el arreglo definitivo prácticamente en cuanto está. Así si por confusión, falta de entendimiento o “la teoria de House” -> “Todos los usuarios mienten” hay que modificar cosas, se modifican, y en cuanto tenemos un momento de respiro, solventar las deudas técnicas que podamos haber dejado colgadas es más sencillo, por que no nos enfrentamos a los cambios, ya están dentro del plan.
    También somos conscientes de que hay temas donde no puedes ir cambiando alegremente a diestro y siniestro, no es que la solución sea tirarse al río sin mirar si hay agua, pero es cuestión de equilibrar las cosas. Si la realidad es que siempre hay cambios imprevistos y que negocio prima sobre desarrollo purista controlado, entonces lo que hay que hacer es adaptarse a esa realidad para que nos sea más llevadera. Como bien dices, al fin y al cabo el objetivo no es cumplir una metodología informática a rajatabla, el objetivo es solucionar el problema, crear el producto etc. de la mejor forma posible, y esa coletilla incluye no dejar “sorpresas” para el futuro, lo cual incluye minimizar deudas técnicas, problemas futuros de mantenimiento etc.

    My 2ec

  3. No se yo si Deuda Tecnica es la mejor manera de describir los sacrificios en calidad en aras de hacer crecer el negocio. Consideras que entras en Deuda de Negocio cuando te dedicas a mejorar la calidad del codigo sin avanzar en el Roadmap?

    Creo que hay una diferencia entre una Startup y el resto de empresas. Lo digo por lo que veo alrededor mio. En los dos anyos que llevo en Techhub he visto morir a algunas Startups, no por que el producto/idea fuera malo, sino por que no llegaron a salir a la superficie y murieron ahogados.

    Una startup es una carrera entre tu equipo, tu idea y tus cojones contra el resto. Y el resto es eso: TODOS!

    Es muy facil, si llegas a tal punto antes de tal fecha vives, si no, mueres… de ahi que se tengan que tomar decisiones: ahora toca correr como si nos persiguiera el mismisimo demonio… y por supuesto, si corres, la probabilidad de que algo no tenga la calidad esperada es alta. Por comparar, lo compararia a pinta una casa. Si eres pintor y te pagan y puedes dedicarle el rato que cada habitacion merce, pues la casa luce de lujo. Si por contra, te levantas a las 6:30, vuelves del curro a las 7 y tienes un monton de paredes por pintar, pues mira, oye, que lo importante es pintar la casa lo mas rapido posible…

    Por que decisiones siempre hay que tomar, pero en una startup, al menos es lo que mi experiencia me ha mostrado, si tu decision no sirve para ganar velocidad y llegar antes a ese punto de seguridad temporal, seguramente es la decision equivocada.

  4. Muy de acuerdo con lo que comentas en el post Aitor, aunque no es que sea algo novedoso, sino que es algo que se sabe, pero no se practica IMHO. Encontrar el equilibrio entre las cosas bien hechas y hechas rápido es muy muy jodido, sobre todo si tienes a alguien (véase cliente / jefe) achuchándote en dinero / tiempo (tiempo == dinero).

    En mi experiencia desde el punto de vista de la empresa, he de confesar que hasta ahora he ido más bien hacia el tiempo, por lo que he cometido bastante deuda técnica para estos proyectos. Mi “excusa” es que como eran apps que sólo se iban a hacer una vez (no se esperaban actualizaciones a largo plazo), pues tampoco había que cuidar muy mucho estos detalles (trato de desarrollar lo más elegante posible, pero ya se sabe que eso es “más difícil” a corto plazo). Desde el punto de vista económico, está claro que es la opción más acertada (insisto, a corto plazo). Desde el punto de vista ‘etico’ / ‘moral’, todo lo contrario.

    En cuanto a la “deuda técnica personal”, mi petproject siempre ha sido OperadorApp, y por eso le he mimado todo lo que he podido. Llegado un día, decidí liberar el código, y como estaba bastante manga por hombro (la razón / excusa aquí es que fue mi primer proyecto en Obj-C, y ya se sabe que el código en un nuevo lenguaje, no siempre es tan bueno como debería), decidí empezar a pagar esa deuda técnica: cuesta, y mucho.
    La parte buena es que aprendes cosas que has hecho mal en un pasado, y que aunque sabías que se podían haber hecho de otra forma, ahora te das cuenta de que incluso aquella manera “tan buena” que pensaste en su momento, tiene una mejor opción.
    Afortunadamente en este tipo de proyectos, el tiempo no es un problema (dentro de unos límites, claro está), por lo que te lo puedes tomar con calma para dejarlo todo como los chorros del oro, o al menos para poder salir a la calle con el código y presumir de que eso lo has hecho tú, que creo que es uno de los mejores ejemplos de que PIENSAS que no has dejado deuda ténica :)

    Ahora mismo me encuentro actualizando una app que hicimos el año pasado para un cliente, y que ahora requiere algunas mejoras. Solo espero no haber dejado demasiada deuda, porque está clarisimo que va a haber que pagarla y de este coste únicamente somos responsable nosotros, como es lógico.

  5. Aitor, que sepas que me has ahorrado un post :) Pero estoy preparando el caso practico :P Como desde la version 1 instalable i en produccion, en 1 año y medio hemos evolucionado gradualmente la arquitectura para volvernos a sentir orgullosa de ella y sin “lastimar” el negocio. Y creo que lo hemos conseguido.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s