Una arquitectura de software sostenible es la que permite seguir añadiendo funcionalidades años después sin que cada cambio rompa algo. No depende de usar el patrón más sofisticado ni la librería más nueva, sino de cuatro cosas: código fácil de leer, tecnologías maduras, reglas de negocio separadas de las herramientas y decisiones documentadas. Cuando falta alguna, el proyecto acumula deuda técnica hasta que la única salida que alguien propone es "reescribirlo todo desde cero".
Casi todos los desarrolladores hemos pasado por esto: entramos a un proyecto con entusiasmo, pero a los pocos meses cada nueva funcionalidad rompe tres cosas existentes. El código se vuelve frágil, las dependencias quedan desactualizadas y refactorizar parece tan arriesgado que nadie se atreve.
Después de 13 años desarrollando software y creando productos digitales, he comprobado que el software no se destruye por falta de líneas de código, sino por malas decisiones de arquitectura tomadas al principio. En este artículo te comparto los principios que aplico para diseñar aplicaciones robustas, escalables y, sobre todo, sostenibles en el tiempo.
¿Por qué el software se vuelve inmantenible en dos años?
El ciclo de vida de un mal proyecto suele ser el mismo:
- Prisa inicial: hay que entregar, y "ya lo ordenaremos después".
- Parches rápidos: cada fallo se tapa donde aparece, no donde se origina.
- Deuda técnica acumulada: cada atajo hace que el siguiente cambio cueste un poco más.
- Sistema inmantenible: nadie entiende el conjunto, y tocar cualquier parte da miedo.
¿Qué es la deuda técnica?
El término lo acuñó Ward Cunningham en 1992: cada atajo que tomas en el código es un préstamo. Te permite ir más rápido hoy, pero pagas intereses en forma de tiempo extra en cada cambio futuro. Un poco de deuda es sana y a veces necesaria para llegar a tiempo. El problema es no saber cuánta tienes ni tener un plan para pagarla.
Cuando el código no se diseña pensando en la evolución, cualquier cambio futuro se vuelve costoso y frustrante, tanto para los desarrolladores como para el negocio que paga esas horas.
Señales de que tu arquitectura se está muriendo
Si reconoces tres o más de estas, el proyecto necesita atención:
- Una funcionalidad pequeña se estima en semanas "porque hay que tocar muchas partes".
- Hay zonas del código que nadie quiere tocar y archivos con miles de líneas.
- Los errores reaparecen: se corrigen en un sitio y vuelven a salir en otro.
- Las dependencias llevan años sin actualizarse porque actualizarlas rompe cosas.
- Un desarrollador nuevo tarda semanas en poder hacer su primer cambio con confianza.
- No hay pruebas automáticas, o las que hay fallan siempre y nadie las mira.
- Las decisiones importantes solo las recuerda la persona que las tomó.
El peligro opuesto: la sobreingeniería
En el otro extremo está el error más común de muchos desarrolladores: construir para un millón de usuarios cuando aún no tienen diez.
Crear microservicios prematuros, capas infinitas de abstracción o configurar infraestructura compleja desde el día uno suele generar una carga de mantenimiento destructiva. Cada pieza extra es algo más que desplegar, vigilar, actualizar y entender.
Principio clave: la arquitectura debe evolucionar con el producto, no anticiparse innecesariamente a él. La verdadera elegancia en ingeniería está en resolver un problema complejo con la solución más simple posible.
¿Monolito o microservicios?
Para la gran mayoría de productos que empiezan, mi respuesta es la misma: un monolito modular. Una sola aplicación, un solo despliegue, pero organizada por dentro en módulos con fronteras claras. Si algún día un módulo necesita escalar por su cuenta, se puede separar sin reescribir el resto.
| Monolito desordenado | Monolito modular | Microservicios | |
|---|---|---|---|
| Complejidad de despliegue | Baja | Baja | Alta: muchos servicios, red, versiones |
| Facilidad para cambiar | Baja: todo depende de todo | Alta dentro de cada módulo | Alta dentro de cada servicio, baja entre ellos |
| Coste de infraestructura | Bajo | Bajo | Alto |
| Equipo que necesita | Cualquiera | Uno o varios desarrolladores | Varios equipos independientes |
| Cuándo tiene sentido | Nunca a propósito | Casi siempre al empezar | Cuando hay equipos y cargas que de verdad lo exigen |
Los microservicios resuelven un problema organizativo, el de muchos equipos trabajando a la vez sin pisarse, más que técnico. Si tu equipo cabe en una mesa, probablemente no lo tienes.
Los 4 pilares del software que perdura
1. Simplicidad y legibilidad
El código se escribe una vez, pero se lee decenas de veces. Si un desarrollador nuevo tarda dos semanas en entender dónde agregar un endpoint, la arquitectura ha fallado.
- Organiza las carpetas por dominio o por funcionalidad, no por capas técnicas infinitas. Así, todo lo relacionado con un tema vive junto.
- Prefiere código explícito antes que abstracciones "mágicas" que ocultan el comportamiento real.
- Nombra las cosas con el vocabulario del negocio. Si en la empresa se dice "pedido", en el código no debería llamarse "transacción".
Un ejemplo de estructura por funcionalidad en una aplicación de pedidos:
pedidos/: rutas, reglas de negocio, acceso a datos y pruebas de todo lo relacionado con pedidos.clientes/: lo mismo para clientes.pagos/: la integración con la pasarela, aislada del resto.compartido/: solo lo que de verdad usan varios módulos.
Frente a la alternativa habitual de controllers/, services/, repositories/ y models/, donde un solo cambio en pedidos te obliga a abrir cuatro carpetas distintas.
2. Elección de stack pragmática
Elegir la última tecnología de moda en redes sociales puede parecer divertido, pero tiene un coste alto: falta de madurez en el ecosistema, cambios drásticos de API y librerías abandonadas.
- Apóyate en tecnologías consolidadas con comunidades fuertes (Node.js, TypeScript, PostgreSQL, Java) para la lógica crítica.
- Reserva la innovación técnica para herramientas que realmente resuelvan un problema específico. Por ejemplo, usar Astro para lograr un rendimiento web excelente sin sobrecargar de JavaScript al navegador.
- Pocas dependencias, y bien elegidas. Antes de instalar una librería, mira cuándo fue su última versión, cuántas personas la mantienen y si puedes resolver lo mismo con unas pocas líneas propias.
- Mantén las dependencias al día de forma regular, con herramientas como Dependabot o Renovate. Actualizar poco y a menudo es mucho más barato que saltar tres versiones mayores de golpe.
3. Desacoplamiento de la lógica de negocio
Las herramientas cambian, las bases de datos se migran, pero las reglas de negocio de tu producto deberían permanecer intactas.
- Aísla la lógica principal de los frameworks y de los servicios de terceros (pasarelas de pago, ORM, proveedores de correo).
- Envuelve cada servicio externo en un módulo propio. Si mañana cambias de pasarela de pagos, solo cambia ese módulo, no las cincuenta partes del código que cobran.
- Aplica Clean Architecture o arquitectura hexagonal de forma pragmática, sin llenar el repositorio de carpetas vacías ni de interfaces que solo tienen una implementación.
La prueba es sencilla: ¿puedes probar una regla de negocio sin levantar la base de datos ni el servidor web? Si la respuesta es sí, tu lógica está bien separada.
4. Testing pragmático y documentación integrada
Documentar no significa escribir un PDF de 50 páginas que nadie leerá.
- Documenta el porqué de las decisiones importantes con registros de decisiones de arquitectura (ADR, Architecture Decision Records) guardados directamente en el repositorio.
- Crea pruebas de integración y de API que validen los flujos clave del sistema, en lugar de perseguir un 100 % de cobertura con pruebas unitarias triviales.
- Automatiza la ejecución de las pruebas en cada cambio (integración continua). Una prueba que nadie ejecuta no protege nada.
Qué incluye un ADR
El formato más usado, propuesto por Michael Nygard, cabe en una página:
- Título: la decisión en una frase ("Usar PostgreSQL como base de datos principal").
- Estado: propuesta, aceptada o reemplazada por otro ADR.
- Contexto: qué problema había y qué restricciones existían.
- Decisión: qué se eligió.
- Consecuencias: qué se gana, qué se pierde y qué habrá que vigilar.
Dentro de dos años, cuando alguien pregunte "¿por qué se hizo así?", la respuesta estará escrita junto al código.
Mi stack de referencia para productos sostenibles
Para garantizar agilidad de desarrollo y rendimiento a largo plazo, esta es la combinación que he validado con el tiempo:
| Capa | Tecnología | Por qué perdura |
|---|---|---|
| Web y contenido | Astro + Tailwind CSS | Cero JavaScript por defecto, buen SEO y carga muy rápida. |
| Aplicaciones web | React / Vue | Ecosistemas maduros y versátiles para interfaces dinámicas. |
| Backend / API | Node.js con TypeScript / Java | Tipado estático, buen rendimiento e integración sencilla. |
| Base de datos | PostgreSQL | Integridad relacional, transacciones fiables y décadas de madurez. |
| Datos flexibles | MongoDB | Para documentos de estructura variable, cuando el modelo relacional estorba. |
| Despliegue | Docker en un VPS | Entornos reproducibles y sin atarte a un proveedor. |
No es un stack obligatorio: es un punto de partida. Lo que importa es el criterio. Tecnologías con años de recorrido, comunidad activa y una razón concreta para estar ahí.
¿Refactorizar o reescribir desde cero?
Cuando un sistema ya está enfermo, la tentación es tirarlo y empezar de nuevo. Casi siempre es un error: la reescritura tarda más de lo previsto, el sistema viejo sigue necesitando cambios mientras tanto y se pierden reglas de negocio que solo estaban escritas en el código antiguo.
La alternativa que funciona es el patrón strangler fig (higuera estranguladora), descrito por Martin Fowler:
- Elige una parte concreta del sistema, la que más duele.
- Constrúyela de nuevo, bien, junto al sistema viejo.
- Redirige el tráfico de esa parte al código nuevo.
- Repite hasta que no quede nada del sistema antiguo.
El negocio nunca se detiene y cada paso entrega valor por sí mismo.
Si no eres técnico: 7 preguntas para quien construye tu producto
Si estás contratando el desarrollo de una aplicación, no necesitas entender la arquitectura para evaluarla. Basta con hacer estas preguntas:
- ¿Otro desarrollador podría continuar el proyecto sin ti? ¿Qué tendría que leer primero?
- ¿Qué tecnologías vas a usar y por qué esas? Desconfía de "porque es lo último".
- ¿Cómo se prueba que un cambio no rompe lo que ya funciona?
- ¿Dónde quedan documentadas las decisiones importantes?
- ¿Qué pasa si mañana quiero cambiar de pasarela de pagos o de proveedor de correo?
- ¿Con qué frecuencia se actualizan las dependencias?
- ¿A nombre de quién quedan el código, el servidor y las cuentas?
Las respuestas claras y concretas son buena señal. Las vagas, o "eso no hace falta todavía" para todo, no lo son.
Preguntas frecuentes
¿Qué es una arquitectura de software sostenible?
La que permite que el producto siga evolucionando durante años con un coste de cambio razonable. Se reconoce porque añadir una funcionalidad cuesta más o menos lo mismo en el tercer año que en el primero.
¿Clean Architecture es obligatoria para que el software dure?
No. Sus ideas —separar la lógica de negocio de los detalles técnicos— son muy valiosas. Aplicarla al pie de la letra en un proyecto pequeño suele añadir más capas de las necesarias. Toma el principio, no la plantilla.
¿Cuándo pasar de monolito a microservicios?
Cuando varios equipos necesitan desplegar partes distintas de forma independiente, o cuando una parte concreta tiene una carga tan diferente que necesita escalar por separado. Si no se da ninguna de las dos, un monolito modular es más simple y más barato.
¿Cuánta cobertura de pruebas necesita un proyecto?
La suficiente para que los flujos críticos estén protegidos: registro, pago, las reglas de negocio centrales. Un porcentaje alto de cobertura con pruebas triviales da una falsa sensación de seguridad.
¿Cada cuánto hay que actualizar las dependencias?
Poco y a menudo: revisiones mensuales y parches de seguridad en cuanto salen. Dejar pasar años convierte una tarea de minutos en un proyecto de semanas.
Conclusión: construir pensando en el futuro
El software que perdura no es el que utiliza el patrón más complejo o la librería más nueva. Es el que es fácil de entender, barato de mantener y rápido de adaptar a los cambios del mercado.
Empieza simple, separa lo que cambia de lo que no, documenta el porqué y protege con pruebas lo que no puede fallar. Con eso, tu producto seguirá creciendo mucho después de los dos años.
¿Estás construyendo un producto digital y quieres que su base aguante el crecimiento? Cuéntame en qué punto estás y te digo qué haría yo. Más detalles en mi servicio de desarrollo de productos digitales. Y si ya tienes un proyecto que se ha vuelto difícil de tocar, en soporte y mantenimiento te explico cómo me hago cargo de código heredado. También puedes escribirme directamente.
Yohan Hernández — Ingeniero de software full stack con 13 años de experiencia construyendo productos web de principio a fin.
Referencias: Ward Cunningham, "The WyCash Portfolio Management System" (OOPSLA, 1992), origen del término deuda técnica; Michael Nygard, "Documenting Architecture Decisions" (2011); Martin Fowler, "StranglerFigApplication" (martinfowler.com).
