legacy vs new

Una de las cosas más complejas en el desarrollo técnico de producto es saber mantener el equilibrio entre lo legacy y estar actualizado e incluso saber cuando hace falta inclinarte a tope hacia un lado o hacia el otro. Tanto si te pasas de conservador como si siempre quieres hacerlo todo nuevo te acabas llevando algunas bofetadas.

Por aclarar antes de lo que hablo voy a mencionar algunos ejemplos.

Caso 1: Seguro que puedo hacer esto mejor

Imagina que tenemos que construir una feature encima de algo que ya existe y funciona. Sin embargo “este algo” no está documentado y el developer que tiene que lidiar con ello no tiene mucha paciencia. Ve que le está costando entenderlo y empieza a pensar que puede rehacer parte de esa arquitectura y que quede más limpia.

A menudo asumimos que podemos hacerlo mejor cuando una arquitectura no sigue exactamente nuestro modelo mental. Ojo, que a veces es verdad, pero si hay algo que no te quema todos los días, igual no está tan mal y resulta que estás un poco biased o no has invertido lo suficiente para entenderlo bien primero.

Caso 2: Sobreingeniería

Otro caso, llegas una empresa y ves que uno de los problemas es la velocidad de desarrollo. Cuando te pones a mirar, te choca que se usa una tecnología que a priori no es simple de usar y te parece que mata moscas a cañonazos.

Asumiento que tu instinto no te falla y no estás biased y que la tecnología en concreto tiene un equilibrio terrible entre el problema que resuelve y la complejidad que acarrea usarla, te acabas planteando que igual lo mejor es reemplazarla.

Caso 3: Tecnología “rota”

Un último ejemplo. El equipo se pega el día apagando fuegos que vienen siempre de la misma parte de la aplicación. Tal vez tienes un modelo con datos redundandates y potencialmente desincronizados. O tal vez estás usando una librería externa compleja que ya no está mantenida por la comunidad y nadie resuelve los bugs.

Tienes que decidir si rehaces una parte significativa de la app para intentar atajar estos problemas o si es mejor seguir estirando la cuerda.


Hay muchas situaciones en el día a día que te hacen plantearte si deberías rehacer algo, dejarlo como está o intentar apañarlo un poco y seguir adelante. Sin embargo los criterios claves para identificar como seguir son casi siempre los mismos.

Criterios para identificar cómo actuar

indy.jpg

De primeras es bueno fiarte un poco de tu “sentido arácnido”. Si llevas un tiempo haciendo esto, puedes usarlo como una alarma que te salte cuando te tienes que enfrentar a una situación así. Y cuando ocurra ya te pones y le dedicas un poco de tiempo a analizar los aspectos técnicos y ponerlos en contexto con los objetivos, el tipo de empresa, los recursos, el tiempo, etc…

Hay una serie de puntos que hay que responder casi siempre cuando se trata de decidir si rehaces algo o te quedas como estás.

Argumentos de peso

  • Por qué lo que hay ahora está mal? Entendemos bien lo que queremos rehacer y por qué? Aún así creemos que hay que hacerlo o estamos tomando el atajo por no intentar entenderlo en condiciones? Se puede arreglar o mejorar antes que rehacer?
  • Cambiar esto añade alguna ventaja competitiva? Va a desbloquear nueva funcionalidad en el producto?
  • Va a aumentar la calidad considerablemente? Si lo hace, cual es el impacto de ese aumento en el día a día? (malo será que no aumente algo, pero hay que ver si vale la pena en el cómputo general)

Urgencia

  • Si nos acabamos de dar cuenta ahora mismo de este problema, seguramente ya hay unos objetivos en el equipo que habría que ver si tiene sentido tocar. Hay que ver cual es el mejor momento para hacerlo. Siendo realistas, cuanto nos desviaría rehacer algo con lo que no contabamos?
  • Si no podemos rehacer esto ahora mismo, qué problemas causaría exactamente el seguir construyendo encima? Hay espacio para un workaround temporal?

Coste

  • Tenemos los skills y tiempo suficientes para atacar este proyecto con garantía de éxito? Cómo sería la transición?
  • El coste de mantenimiento va a ser mayor o menor a la larga? De qué tipo de mantenimiento estamos hablando?
  • Hacen falta más o menos recursos “físicos” para mantener esto? (infraestructura, servicios nuevos…)

Riesgo

  • Conocemos bien el alcance de lo que queremos cambiar? Donde nos podemos encontrar sorpresas al hacer el cambio? Qué impacto puede tener en la app si no lo hacemos bien?
  • Tenemos gente suficiente en el equipo (o es fácil encontrar gente suficiente) en caso de que lo que pretendemos reemplazar sea core en la plataforma? No queremos que algo core dependa de una o dos personas únicamente

Decisiones objetivas

De entrada todos tenemos siempre algún bias. En la forma más simple es común ver cosas como: “puedo hacer el código más simple”, “esta DB es mejor”, “este lenguaje de programación lo uso en mi tiempo libre para pet projects y me gustaría usarlo”, etc…

Cuesta horrores encontrar gente que es consciente de este problema y tiene la constancia suficiente como para mirar más allá cuando se trata de una decisión técnica de cierta relevancia.

Para aliviar una posible tendencia a tomar decisiones biased siempre se pueden introducir ciertos mecanismos en el equipo y una cultura que promuevan un análisis un poco más objetivo en el contexto de lo que necesita el producto.

Code Reviews

Es lo más básico para unificar el “tono” en cualquier equipo de desarrollo. Las expectativas en las CRs tienen que ser muy claras para sean efectivas y que nadie se salga de la dirección que tiene que llevar el equipo. El problema con las CRs es que tienen un alcance limitado. Son muy efectivas para alinear el equipo en valores técnicos de bajo nivel como el estilo de código, pero empiezan a no serlo tanto cuando toca areas de experiencia menos cultivadas como modelos de datos, arquitectura de servicios, procesos en background, etc… Además de que una PR que tiene cambios demasiado significativos a nivel de aruitectura requiere mucho más tiempo y foco para revisarla bien.

Pair programmning

Va un poco en la misma linea de las CRs en cuanto al scope de los cambios que se están haciendo. Es maravilloso para avanzar con problemas un poco rebuscados, para hacer coaching de alguien nuevo o alguien junior y en general también para mantener un poco la sanidad mental en trabajo remoto. Pero una vez más, se suele a quedar corto en temas de arquitectura, especialmente porque es muy fácil que dos personas que hacen pair programming tengan bias y backgrounds similares.

La pizarra

Discutir arquitectura delante de una pizarra es impagable. El tira y afloja, discutir, poner pegas, hacer de abogado del diablo, hacer propuestas poco tradicionales y poco a poco ir pintando. Yo me divierto bastante y es, de lejos, lo más efectivo para valorar decisiones que involucran cambios grandes.

Sin embargo, es la dinámica que más cuesta llevar para adelante trabajando en remoto (especialmente si es async, obviamente) y en entornos multiculturales donde cada persona se comunica de una forma algo distinta. Y por supuesto porque en remoto se pierde mucha velocidad de comprensión y se explica todo mucho peor. Todavía no he encontrado un método perfecto que te de una agilidad y comodidad similares a la de una pizarra en discusiones de este tipo. (si has probado algo similar y te funciona, por favor cuéntamelo 🙏)

RFCs

Trabajando en equipos remotos y especialmente si es async, los RFC (Request For Comment) funcionan muy muy bien. En Sketch decidimos meter el mecanismo junto con una reorganización de tech y producto. Pasando de equipos horizontales puro tech (back, front, mac, …) a verticales multifuncionales es fácil perder esa experiencia de grupo dentro de cada disciplina y hace más falta un mecanismo que permita desafiar, como equipo, decisiones técnicas significativas.

Los RFCs tienen sus cositas también. Hay que poner unas reglas claras para no obcecarse con consenso y paralizar cambios. También tienen que quedar claras las expectativas en los RFC sobre el nivel de detalle y qué se espera de la gente que comenta (un poco como en las PRs en realidad). Y sobre todo hay que perder el miedo a escalar una RFC y también a tirarla a la basura si llegados a cierto punto se ve que no era lo correcto (se hacen a veces auténticas barbaridades por el miedo o la verguenza a tirar algo a la basura en lo que hemos invertido ya algo de tiempo).

PoCs

Relacionado con los RFC, la forma definitiva de probar un cambio potencialmente grande, es haciendo una PoC (Proof of Concept). Pones un scope muy específico para responder las incognitas más grandes en muy poco tiempo. Controlas cuando hacerla para que no te trastoque el roadmap y al final vas a tener la respuesta de si esto funcionará como esperas y también te habrás encontrado con una cantidad de problemas lo suficientemente grandes como para darte una idea de si va a ser un camino de rosas.

A parte del aspecto puramente práctico, las PoC son un buen sistema para subir la moral. La inmersión en la PoC, la intensidad y el hecho de estar probando algo potencialmente revolucionario en el equipo es muy excitante. Si se hacen bien, incluso si acabas tirando a la basura toda la PoC, lo que te llevas de aprendizaje y disfrute no tiene precio.

El papel de leadership

El recurso más importante al final es que leadership esté ahí para intentar explicar donde está el listón técnico. Qué es aceptable y qué no. Cual es el estado del producto en cuanto a velocidad vs finesse. Y estar ahí quiere decir repetir el mantra, poner objetivos claros y participar en discusiones, cómo mínimo de alto nivel.

La comunicación de leadership tiene que ser super clara en cuanto a expectativas. Es fundamental ser directo y claro con los “por qués” de si una decisión es la adecuada o es una barbaridad.

Los objetivos también son fundamentales. No puedes asumir que todo el mndo en el equipo va a tomar las decisiones como las tomaría el CTO, por ejemplo, si no pones objetivos claros y/o límites a la hora de tirar por un lado o por otro. Se puede (y debe) dejar mucho espacio para el equipo para que implementen las cosas de una forma o de otra, pero tienen que saber cuales son los límites y por qué.

Mención especial: Hype Driven Development

No nos damos cuenta cuando estamos hipnotizados por el hype, pero a veces la liamos por usar una tecnologia en nuestra app porque hay una nueva forma de hacer algo de la que todo el mundo habla.

Esto no quiere decir que lo hagamos de mala fe. Casi siempre es inconsciente y si no estamos acostumbrados a buscar otros puntos de vista podemos no darnos cuentas de que no estamos siendo objetivos.

Hay muchos ejemplos de tecnologías que nacen dando haciendo mucho ruido, con muy buen marketing y una comunidad grande, pero que no son para todos los casos, como kubernetes, graphql, elixir, o las múltiples corrientes alrededor del testing en desarollo. En estos casos además se habla mucho de lo bueno, pero muy poco de los problemas por detrás que son los que te pueden arruinar la vida.

Una vez más más, especialmente para no herir sensibilidades, todas tienen sus casos de uso perfectos. Pero hay que tener cuidado con no dejarse llevar por el ruido. Debemos pensar de forma muy objetiva si ese caso de éxito de la que hablan otras empresas van a aplicar e nuestra situación y resolver nuestro problema específico sin añadir nuevos.

Si piensas que una nueva tecnología es la ideal pero no eres capaz de describir objetivamente cómo resuelve tu problema particular (no el hipotético), es mejor dejarlo a un lado de momento y centrarte en tu problema.

Ahora bien, y esto es importante, no te aisles de los avances técnicos. Estate atento a la innovación porque de vez en cuando, alguien crea algo que le puede dar un boost real a tu aplicación y que marque la diferencia en valor, performance, calidad, velocidad, etc…

Consejos finales

Antes de acabar debo decir que igual de malo es la “parálisis por analisis” que tirar siempre para adelante con anteojeras. No hay que pasarse de hacer análisis como si estuvieramos haciendo ciencia de cohetes, pero hay que aplicar un poco de sentido común a decisiones potencialmente destructivas.

Algunos consejos que resumen un poco todo esto:

  • Cuesta cogerle el tino a este equilibrio. Es una habilidad poco común, dificil de desarrollar y requiere, para empezar, capacidad para entender el conjunto de tecnología, producto y negocio y segundo tener una mente analítica pero pragmática al mismo tiempo. Si eres developer, aprende a hilar fino en estos temas y si eres un manager, contrata gente que sepa hacerlo y/o se muy insistente en cultivar esta habilidad en tu equipo
  • Es imperativo que todo el leadership esté siempre ahí para enseñar con el ejemplo, repetir el mantra y poner los mecanismos para que la gente sea autónoma. Hay un montón de mecanismos que ayudan a que estas decisiones sean objetivas y alineadas con la dirección de la empresa. Cuanto antes los identifiques y hagas hincapié más alineado estará todo el equipo
  • Ten cuidado con dejarte llevar por el hype. Coge lo que le funciona a otros, analizalo, pruebalo, pero ten objetividad en cuanto a si resuelve tu problema verdaderamente. Si no es así, cuentaselo igualmente a tus colegas. Es un buen aprendizaje, pero descartalo para tu caso de uso
  • Cuando te enfrentes a una decisión de rehacer una tecnología, arreglarla o dejarla como está, antes de nada, comienza por invertir tiempo en entender muy bien lo que ya está hecho, por qué está hecho así y la naturaleza de los problemas que pueda tener. Si esto no lo tienes claro, no deberías ni de pensar en cómo cambiarlo
  • Una vez que entiendas lo que hay, piensa en los costes de desarrollo, aprendizaje y mantenimiento. Pero ojo, no te quedes solo en la parte técnica. Es fundamental que te hagas otras preguntas como:
    • Mantener algo que da problemas está afectando a los objetivos o la reputación del producto?
    • Rehacer algo de otra manera va a aportar una ventaja competitiva o abrir alguna puerta al producto?