La sobreingeniería puede matar a tu startup
Descubre por qué la sobreingeniería es uno de los mayores peligros para tu startup o producto digital. Analizamos qué es y cómo prevenirla.
Hace unos días publiqué en Twitter una reflexión sin ningún motivo aparente, pero que me ha servido de inspiración para escribir el post de esta semana:
Creo que es un tema especialmente importante porque la sobreingeniería es capaz de hacer quebrar a cualquier empresa. Así, el post de hoy no va dirigido tan sólo a Product Managers como es habitual, si no que Fundadores, Inversores, o cualquier otro perfil con skin in the game en un producto o servicio digital también podría sacarle partido.
Antes de comenzar, y para que no me acusen de meterme en camisas de once varas, comentaré que antes de Product Manager fui ingeniero. De hecho, mi formación es en Ingeniería Informática. Si bien siempre he estado más cerca del negocio que de la programación, durante mi carrera he creado, escalado y gestionado equipos tanto de ingeniería como de producto a partes iguales.
Sin más dilación, comencemos por el principio.
¿Qué es la sobreingeniería?
Si nos vamos a la definición estricta de la Wikipedia, la sobreingenería se refiere al hecho de diseñar un producto de forma más compleja de lo necesario:
Overengineering (or over-engineering,[1] or over-kill) is the act of designing a product or providing a solution to a problem in an overly complicated manner, where a simpler solution can be demonstrated to exist with the same efficiency and effectiveness as that of the original design.[2] — Wikipedia
En el contexto del software, me gusta esta definición de Paweł Głogowski:
Code or design that solves problems you don’t have.
Ahora pensaréis, ¿quién diseña o programa para resolver un problema que no tiene? Parece ridículo, ¿verdad? Pues agarraros a la silla porque, después de dos décadas de carrera y habiéndolo hecho yo mismo, os puedo asegurar que la sobreingeniería no es la excepción, es la norma.
Causas de la sobreingenería
Obviamente, nadie lo hace con mala intención. De hecho en muchas ocasiones la sobreingeniería se produce por querer anticipar el futuro y estar preparados ante lo desconocido.
Cuando programamos una funcionalidad, es fácil pensar que invirtiendo un poquito de tiempo más lo podemos dejar preparado “por si acaso” en el futuro tuviéramos que hacer esto otro.
La realidad es que nueve de cada diez veces ese por si acaso nunca llega. Pero en el camino hemos perdido un valioso tiempo y, lo que es peor, hemos incrementado la complejidad del proyecto, algo que arrastraremos a lo largo de toda la vida del mismo.
Otra causa de la sobreingeniería suele ser la falta de experiencia. En general, cuánto más sénior eres, menos ganas de fliparte tienes porque ya has vivido bastantes situaciones donde la complejidad artificial te ha explotado en la cara.
La curva de aprendizaje respecto a la experiencia de un ingeniero suele seguir un patrón bastante parecido a este:
Empiezas programando código sencillo.
Descubres un paradigma como podría ser la programación orientada a objetos y te subes al carro.
Lees sobre patrones de diseño y empiezas a buscar la oportunidad para implementarlos en cada proyecto.
Tras unos años de haber sufrido la complejidad innecesaria en tus carnes, vuelves a escribir código sencillo.
Los requisitos poco definidos obviamente también incrementan este problema. Si un ingeniero no tiene bien acotado un problema, tenderá a la sobreingeniería para protegerse de la incertidumbre.
El aburrimiento también puede generar sobreingeniería. Si un ingenierio no tiene retos interesantes a los que enfrentarse es posible que termine complicando cualquier problema por el simple hecho de probar algo nuevo.
Consecuencias de la sobreingeniería
Cuando decía al principio del artículo que la sobreingeniería mata startups, no lo decía de broma. Esta tiene dos efectos particularmente perversos en cualquier sistema.
Por una parte, aumenta el coste de desarrollo. Si nuestros ingenieros no eligen la solución más sencilla para abordar un problema, nuestro coste de desarrollo en tiempo y dinero aumenta, lo que evitará que iteremos más rápido.
Por otra parte, también aumenta el coste de mantenimiento. El código sencillo es mucho más fácil de programar, probar y modificar. Cuando lo complicamos, la complejidad puede aumentar de forma exponencial, de nuevo impactando en nuestra velocidad de iteración.
Así pues, me reafirmo. La sobreingeniería mata startups. Mucho más que la ausencia de buenas prácticas. Y es que para cobrar el beneficio de las buenas prácticas hay que llegar a tener encaje en el mercado, pero la sobreingeniería puede evitar que llegues a tenerlo.
Ejemplos de sobreingenería
El primero que me viene a la mente son las arquitecturas basadas en microservicios. Llegaron como una ola hace unos años y se deben haber llevado más proyectos por delante de los que han consolidado.
Las pongo como ejemplo de sobreingeniería porque en el 99% de los casos no son necesarias, especialmente para una startup que tenga que encontrar market-fit. Dedícate a encontrarlo a lomos de un majestuoso monolito que te permita iterar a toda velocidad. Si lo encuentras y resulta que terminas necesitando pasarte a microservicios, significará que has alcanzado una escala considerable y oye, ese es un bendito problema a tener.
La optimización prematura suele ser otro ejemplo típico de sobreingeniería. Preparar un sistema para operar con latencias muy bajas o absorber gran cantidad de tráfico cuando, ni tienes usuarios, ni probablemente sepas cómo serán y qué nivel de servicio necesitarán. Vuelvo arriba. En la mayoría de los casos, con un monolito corriendo en un único servidor te servirá para validar tu modelo de negocio.
Uno de los peores ejemplos de optimización prematura se da cuando nos pasamos mucho tiempo diseñando un sistema para evitar repetirnos en el futuro y tener que tirar parte del trabajo hecho. Créeme, de nada sirve diseñar un sistema si no llegas a verlo en funcionamiento porque has quebrado antes. El peor código del planeta que te ayude a validar una hipótesis es mejor que quedarte parado por miedo a no repetirte.
Relacionado con lo anterior, las reescrituras son un ejemplo clarísimo de sobreingeniería. A ningún ingeniero le gusta mantener código que ha hecho otro ingeniero. La tendencia natural es a querer hacerlo todo siempre de cero. Pero como Joel escribió hace más de 20 años en Things you should never do, las reescrituras raramente cumplen su propósito y pueden llevarse a tu empresa por delante.
Suena hasta raro decirlo por lo evidente, pero a tu cliente no le importa lo más mínimo lo elegante que sea tu sistema por dentro. A tu cliente le importa que le ayudes a resolver su problema. Todo minuto invertido en no darle valor es un minuto perdido.
¿Cómo prevenir la sobreingeniería?
La mejor forma de prevenir la sobreingeniería desde mi punto de vista es convertir a tus ingenieros en verdaderos ingenieros de producto.
Eso se consigue involucrándolos en el día a día del negocio, explicándoles el por qué de cada iniciativa que se plantea, enlanzándola con las métricas que importan para la organización y con la visión de la misma.
También acercándoles a los usuarios, invitándolos a entrevistas y sesiones de discovery con ellos. Quieres que tu equipo empatice con tu cliente o usuario, de forma que consideren un desperdicio todo lo que no sea resolver sus problemas de la forma más eficiente posible.
Si tratas a tus ingenieros como meras piezas de un engranaje cuya única tarea es implementar historias de usuario que aparecen por arte de magia en un backlog, no esperes que estén motivados por evitar complejidad.
Relacionado con lo anterior, define bien el problema para reducir la ambigüedad. Tus ingenieros necesitan saber el por qué, pero también necesitan saber qué se espera de ellos. Cuánto más puedas acotar el problema, menos razones tendrán para protegerse. Una buena forma de definir las expectativas de un sistema es utilizando objetivos de servicio utilizando SLIs y SLOs.
Los ingenieros son de los perfiles más creativos en cualquier empresa. Si tu equipo confía en tu criterio, es probable que en el día a día surjan ideas o iniciativas de su parte que puedan evidenciar que están pensando en un caso de uso futuro. Cuando tengas la intuición de que esto pueda ser así, pregunta: ¿Cómo ayuda esto a resolver el problema actual de nuestros usuarios? ¿Qué sucede si no lo hacemos ahora? La respuesta te ayudará a discriminar si realmente se trata de un posible caso de sobreingeniería o no. Recuerda la importancia de mantener el foco.
Por último, más orientado a fundadores, contrata en lo posible a ingenieros sénior que ya hayan tenido unas cuántas experiencias en empresas de producto. Busca cicatrices de guerra durante las entrevistas. Pregunta por sus experiencias más dolorosas y cómo hicieron para solventarlas. Quédate con aquellos que ponen por delante al usuario y la simplicidad antes que la tecnología.
Un error común suele ser considerar la tecnología como cuello de botella. En muy pocas ocasiones realmente lo es. Cualquier ingeniero sénior puede programar en cualquier otro lenguaje con un periodo mínimo de adaptación.
Modelos mentales para prevenir la sobreingeniería
YAGNI
El problema de la sobreingeniería es tan evidente en la industria que los propios ingenieros tienen un término para referirse al hecho de añadir una funcionalidad “por si acaso”: YAGNI, acrónimo de “You are not going to need it”.
Básicamente YAGNI trata de evitar que añadas nada que no sea estrictamente necesario para resolver el problema que tienes delante de ti porque, aunque lo creas muy fuerte, la realidad es que muy probablemente “no lo vas a necesitar”.
KISS
El término KISS, Keep it simply stupid (“mantenlo estúpidamente simple”) hace referencia al hecho de que los sistemas sencillos son más fáciles de reparar, evolucionar y mantener. Por lo tanto, la simplicidad debe ser uno de los objetivos de cualquier diseño, evitando cualquier complejidad innecesaria.
Worse is better
Con Worse is better, o “cuánto peor mejor”, resaltamos que llega un punto en el que tener menos opciones es preferible a tener más, porque puede simplificar el uso de nuestro producto y hacerlo atractivo a un segmento más amplio del mercado.
En otras palabras, nos incita a mantener las funcionalidades mínimamente imprescindibles de un producto, evitando añadir grasa pueda añadir complejidad al mismo.
Addition by Subtraction
Relacionado con lo anterior, otro modelo mental que nos puede ayudar a prevenir la sobreingeniería consiste en mejorar un sistema eliminando partes completas del mismo que ya no son necesarias. Escribí sobre ello en este post.
Conclusión
La sobreingeniería tiene el potencial de destruir tu startup:
Añadiendo complejidad innecesaria.
Incrementando los costes de desarrollo y mantenimiento.
Reduciendo tu velocidad de iteración.
Evitando así que llegues a obtener encaje en el mercado.
Lamentablemente, la sobreingeniería no es una excepción, es la norma. Por ello es vital saber en qué consiste y tratar de prevenirla principalmente involucrando y acercando a tus ingenieros a los problemas reales de tus clientes.
Todo minuto que invirtamos en el desarrollo que no vaya orientado a resolver un problema de nuestros usuarios es un minuto perdido. Evita caer en la trampa de los “por si acaso”.
El cementerio está lleno de startups y productos exquisitamente diseñados para escalar a millones de usuarios que nunca llegaron a tener la más mínima tracción. No te conviertas en uno de ellos.
📝 Referencias
The complexity unlearning curve — Rob Kerr
The Over-Engineering Problem (And How to Avoid It) — ProFocus Technology
Overengineering: Why We Do It and 10 Ways to Tackle It — Amanda Woo
Seven Questions You Can Ask to Prevent Overengineering — Mark Snyder
🙌 ¡Comparte!
Cómo siempre, muchas gracias por estar ahí. Si te ha gustado el post y crees que le podría interesar a alguien de tu entorno sé libre de reenviarle este correo. También puedes utilizar estos enlaces para compartirlo directamente en Twitter o LinkedIn y así contribuirás a que esta lista llegue a más gente.
Muchísimas gracias de antemano, Simón.
excelente
Un post muy necesario!