Si hay una frase que resume el oficio del arquitecto es esta: "depende". Casi ninguna decisión arquitectónica es buena o mala en absoluto; es buena o mala para un contexto concreto y unas prioridades concretas. Diseñar un sistema consiste, en el fondo, en una cadena de decisiones donde ganar en un atributo casi siempre implica ceder en otro. A estos sacrificios deliberados los llamamos trade-offs o compromisos. En esta lección aprenderás qué hace que una decisión sea "arquitectónica", cuáles son los compromisos más universales (empezando por el teorema CAP), cómo documentar decisiones con ADR y cómo evaluar arquitecturas de forma estructurada con el método ATAM.
Contenido
- Qué es una decisión arquitectónica significativa
- El concepto de trade-off
- Trade-offs clásicos
- El teorema CAP
- Documentar decisiones: los ADR
- Evaluar la arquitectura: el método ATAM
- Qué es una decisión arquitectónica significativa
No toda decisión técnica es arquitectónica. Una decisión es arquitectónicamente significativa (lo que la literatura llama Architecturally Significant Decision) cuando cumple una o varias de estas características:
- Alto coste de cambio: revertirla implicaría reescribir partes importantes del sistema.
- Amplio alcance: afecta a varios componentes, equipos o atributos de calidad.
- Impacto en atributos de calidad: condiciona el rendimiento, la seguridad, la disponibilidad, etc.
- Crea o elimina restricciones: abre o cierra opciones futuras.
Ejemplos de decisiones significativas: elegir entre monolito y microservicios, escoger el modelo de consistencia de datos, definir el mecanismo de autenticación, seleccionar el estilo de comunicación entre servicios. Ejemplos de decisiones no significativas: el nombre de una variable, el formato de indentación, qué librería de utilidades menor usar.
- El concepto de trade-off
Un trade-off es un intercambio: para ganar algo, cedes otra cosa. En arquitectura, los recursos y los atributos de calidad están en tensión permanente.
graph LR
D["Decisión:<br/>añadir caché"]
D --> R["+ Rendimiento"]
D --> C["- Consistencia<br/>(datos posiblemente obsoletos)"]
D --> M["+ Complejidad<br/>(invalidación de caché)"]Este diagrama Mermaid (graph LR, de izquierda a derecha) muestra que una sola decisión —añadir una caché— produce simultáneamente un efecto positivo (más rendimiento) y dos negativos (menos consistencia y más complejidad). La lección clave es que toda decisión tiene consecuencias en varias dimensiones a la vez, y el trabajo del arquitecto es hacerlas explícitas para decidir con los ojos abiertos.
La pregunta correcta nunca es "¿es buena esta opción?", sino "¿qué gano, qué pierdo, y compensa dadas mis prioridades?".
- Trade-offs clásicos
Estos compromisos aparecen una y otra vez en cualquier sistema:
| Trade-off | Un extremo | El otro extremo | Cómo decidir |
|---|---|---|---|
| Consistencia vs disponibilidad | Datos siempre correctos | Sistema siempre responde | Según el dominio (banca vs red social) |
| Coste vs rendimiento | Infraestructura barata | Respuesta ultrarrápida | Según el valor de la latencia para el negocio |
| Simplicidad vs flexibilidad | Solución directa y rígida | Solución genérica y configurable | Según cuánto cambio se prevé |
| Time-to-market vs deuda técnica | Lanzar ya, atajos | Construir bien, más lento | Según la fase del producto |
| Acoplamiento vs autonomía | Componentes integrados | Servicios independientes | Según necesidad de despliegue autónomo |
| Monolito vs microservicios | Simple de desarrollar/desplegar | Escalable y autónomo por partes | Según tamaño de equipo y necesidades de escala |
Veamos el último en detalle:
| Criterio | Monolito | Microservicios |
|---|---|---|
| Complejidad inicial | Baja | Alta |
| Despliegue | Una unidad | Muchas unidades independientes |
| Escalado | Todo o nada | Selectivo por servicio |
| Consistencia de datos | Sencilla (una BD, transacciones) | Compleja (consistencia eventual) |
| Coste operativo | Bajo | Alto (orquestación, observabilidad) |
| Mejor para... | Equipos pequeños, dominios no enormes | Organizaciones grandes con dominios bien delimitados |
La conclusión habitual: empezar con un monolito bien estructurado (a veces llamado "monolito modular") y extraer microservicios solo cuando el dolor concreto lo justifique. Saltar directo a microservicios "porque es lo moderno" es un error costoso muy frecuente.
- El teorema CAP
El teorema CAP, formulado por Eric Brewer, es el trade-off más famoso de los sistemas distribuidos. Afirma que un sistema distribuido no puede garantizar las tres propiedades siguientes simultáneamente, solo dos:
- C — Consistencia (Consistency): toda lectura recibe el dato más reciente o un error.
- A — Disponibilidad (Availability): toda petición recibe una respuesta (aunque no sea el dato más reciente).
- P — Tolerancia a particiones (Partition tolerance): el sistema sigue funcionando aunque se pierda la comunicación entre nodos.
La clave que muchos pasan por alto: en un sistema distribuido real, las particiones de red ocurren, no son opcionales. Por tanto, la P es obligatoria, y la elección real es entre C y A cuando hay una partición.
graph TD
P["¿Hay partición de red?"]
P -->|"No"| N["Funciona con C y A normalmente"]
P -->|"Sí"| E["Hay que elegir:"]
E --> CP["CP: priorizar Consistencia<br/>(rechazar peticiones para no dar datos erróneos)"]
E --> AP["AP: priorizar Disponibilidad<br/>(responder aunque el dato no esté actualizado)"]Este diagrama Mermaid ilustra que el dilema CAP solo se manifiesta durante una partición. Cuando no hay partición, un sistema puede ofrecer consistencia y disponibilidad. Cuando la hay, debe elegir: un sistema CP prefiere rechazar peticiones antes que devolver un dato incorrecto (típico en banca); un sistema AP prefiere seguir respondiendo aunque el dato pueda estar desactualizado (típico en redes sociales o catálogos).
| Tipo | Elige | Ejemplo de uso | Ejemplo de tecnología |
|---|---|---|---|
| CP | Consistencia | Saldo bancario, inventario crítico | Bases de datos relacionales en clúster, MongoDB (configurable), HBase |
| AP | Disponibilidad | Carrito de la compra, feed social | Cassandra, DynamoDB, Riak |
Un matiz importante: en la práctica, la consistencia no es binaria. Muchos sistemas usan consistencia eventual, donde los datos convergen al valor correcto tras un breve periodo. El modelo PACELC extiende CAP para considerar también el trade-off entre latencia y consistencia cuando no hay particiones.
- Documentar decisiones: los ADR
Una decisión arquitectónica que solo vive en la cabeza de quien la tomó está perdida. Los ADR (Architecture Decision Records, registros de decisiones arquitectónicas) son documentos breves que capturan una decisión y, sobre todo, su porqué. Popularizados por Michael Nygard, son hoy una práctica estándar.
Un ADR típico tiene esta estructura:
# ADR-007: Usar mensajería asíncrona entre Pedidos y Envíos ## Estado Aceptada (2026-03-15) ## Contexto El servicio de Envíos sufre caídas ocasionales. Hoy Pedidos lo llama de forma síncrona, de modo que una caída de Envíos provoca errores visibles al cliente y bloquea la creación de pedidos. Necesitamos desacoplar ambos servicios y mejorar la disponibilidad de la creación de pedidos. ## Decisión Pedidos publicará un evento "PedidoCreado" en un broker de mensajería. Envíos consumirá ese evento de forma asíncrona. Pedidos ya no llamará directamente a Envíos. ## Consecuencias Positivas: - La creación de pedidos no depende de la disponibilidad de Envíos (mayor disponibilidad). - Los servicios quedan desacoplados y pueden desplegarse por separado. Negativas: - Se introduce consistencia eventual: el envío se procesa con un pequeño retardo. - Mayor complejidad operativa: hay que operar y monitorizar el broker. - Hay que gestionar mensajes duplicados y el orden de eventos.
Este ADR está escrito en Markdown y sigue el formato de Nygard. Las secciones clave son: Estado (propuesta, aceptada, obsoleta, sustituida), Contexto (el problema y las fuerzas en juego), Decisión (qué se decide, en presente y de forma afirmativa) y Consecuencias (los trade-offs, tanto buenos como malos, escritos honestamente). Lo más valioso es la sección de Consecuencias negativas: documentar lo que sacrificamos evita que en el futuro alguien "redescubra" el problema y cuestione la decisión sin entender por qué se tomó. Los ADR se guardan versionados junto al código (por ejemplo, en una carpeta docs/adr/).
- Evaluar la arquitectura: el método ATAM
¿Cómo saber si una arquitectura propuesta es adecuada antes de construirla? El ATAM (Architecture Tradeoff Analysis Method), desarrollado por el SEI, es un método estructurado para evaluar arquitecturas analizando precisamente sus trade-offs frente a los atributos de calidad prioritarios.
Pasos esenciales del ATAM (simplificados):
- Presentar el método a los participantes (negocio y técnicos).
- Presentar los business drivers: objetivos de negocio y atributos de calidad prioritarios.
- Presentar la arquitectura propuesta.
- Identificar enfoques arquitectónicos (patrones y tácticas usados).
- Construir el árbol de utilidad (utility tree): se descomponen los atributos de calidad en escenarios concretos, priorizados por importancia y por riesgo.
- Analizar los enfoques frente a los escenarios prioritarios.
- Identificar puntos clave, en tres categorías.
- Presentar resultados.
En el paso 7, ATAM clasifica los hallazgos en tres tipos muy útiles incluso fuera del método formal:
| Concepto | Definición |
|---|---|
| Punto sensible (sensitivity point) | Una decisión que afecta de forma decisiva a un atributo de calidad |
| Punto de compromiso (tradeoff point) | Una decisión que afecta a varios atributos en sentidos opuestos (un trade-off explícito) |
| Riesgo | Una decisión que podría tener consecuencias negativas dadas las prioridades |
ATAM completo es un proceso pesado, pensado para sistemas críticos. Pero su filosofía es aplicable siempre: evalúa la arquitectura contra escenarios de calidad priorizados y haz explícitos los puntos de compromiso y los riesgos. Incluso una versión ligera, en una pizarra y un par de horas, aporta enorme valor.
Errores Comunes y Consejos
- Tomar decisiones por moda. "Microservicios porque está de moda" ignora el contexto. Decide según tus atributos prioritarios, no según el hype.
- No documentar el porqué. Sin ADR, las decisiones se cuestionan eternamente y se pierde el conocimiento al rotar el equipo.
- Ocultar las consecuencias negativas. Un buen ADR es honesto sobre lo que se sacrifica. Maquillar los trade-offs lleva a sorpresas dolorosas.
- Creer que existe la decisión "correcta". Casi todo es un compromiso. Busca la decisión adecuada para tus prioridades, no la perfecta.
- Consejo: prioriza antes de decidir. Pide al negocio que ordene los atributos de calidad. Sin prioridades, no se pueden resolver los trade-offs.
Ejercicios
Ejercicio 1. Para un sistema de saldos bancarios y para un feed de una red social, indica si elegirías CP o AP ante una partición de red, y justifícalo.
Ejercicio 2. Escribe un ADR breve (estado, contexto, decisión, consecuencias) para la decisión "Adoptar una base de datos relacional única en lugar de una base de datos por microservicio" en una aplicación que aún es pequeña.
Ejercicio 3. En la decisión "introducir una caché distribuida delante de la base de datos", identifica un punto sensible, un punto de compromiso y un riesgo según la terminología de ATAM.
Soluciones
Solución 1. Saldos bancarios: CP. Es preferible rechazar una operación (no estar disponible momentáneamente) antes que mostrar o permitir operar sobre un saldo incorrecto; la consistencia es crítica. Feed de red social: AP. Es preferible seguir mostrando contenido (aunque falte la última publicación) antes que dejar de responder; la disponibilidad pesa más que ver el dato exacto al instante.
Solución 2. Ejemplo: Estado: Aceptada. Contexto: La aplicación es pequeña, el equipo reducido y el dominio aún no está estabilizado; gestionar varias bases de datos añadiría complejidad operativa y de consistencia sin beneficio claro. Decisión: Usar una única base de datos relacional compartida por los módulos, manteniéndolos lógicamente separados (monolito modular). Consecuencias: Positivas: transacciones simples, consistencia fuerte, menor coste operativo, desarrollo más rápido. Negativas: acoplamiento a un único esquema, posible cuello de botella al escalar y mayor esfuerzo futuro si se quiere migrar a base de datos por servicio.
Solución 3. Punto sensible: el tiempo de expiración (TTL) de la caché afecta decisivamente al rendimiento (cuánto se aprovecha la caché). Punto de compromiso: la caché mejora el rendimiento pero perjudica la consistencia (datos potencialmente obsoletos) y aumenta la complejidad. Riesgo: una estrategia de invalidación incorrecta podría servir datos obsoletos a los usuarios o, peor, provocar incoherencias difíciles de detectar.
Conclusión
Has aprendido a reconocer qué hace que una decisión sea arquitectónicamente significativa, a razonar en términos de trade-offs, a manejar los compromisos clásicos y el teorema CAP, a documentar decisiones con ADR honestos y a evaluar arquitecturas con la filosofía de ATAM. La idea que vertebra todo el capítulo es que la arquitectura es el arte de elegir conscientemente qué sacrificar. Pero de nada sirven decisiones brillantes si nadie las entiende ni puede comunicarse al equipo: en la siguiente y última lección del módulo aprenderás a documentar la arquitectura mediante vistas y el modelo C4, para que tus decisiones se transmitan con claridad.
Curso de Arquitectura de Aplicaciones
Módulo 1: Fundamentos de la Arquitectura de Aplicaciones
- ¿Qué es la Arquitectura de Aplicaciones?
- El Rol del Arquitecto de Software
- Atributos de Calidad y Requisitos No Funcionales
- Decisiones Arquitectónicas y Compromisos (Trade-offs)
- Documentación de Arquitectura: Vistas y el Modelo C4
Módulo 2: Principios y Tácticas de Diseño
- Acoplamiento, Cohesión y Separación de Responsabilidades
- Principios SOLID Aplicados a la Arquitectura
- DRY, KISS, YAGNI y Otros Principios de Diseño
- Tácticas Arquitectónicas para los Atributos de Calidad
- Gestión de la Deuda Técnica
Módulo 3: Estilos y Patrones Arquitectónicos
- Arquitectura Monolítica
- Arquitectura en Capas (N-Tier)
- Arquitectura Cliente-Servidor
- Arquitectura Hexagonal (Puertos y Adaptadores)
- Arquitectura Limpia y Cebolla (Clean & Onion)
Módulo 4: Arquitecturas Distribuidas y Microservicios
- Introducción a los Sistemas Distribuidos
- Arquitectura de Microservicios
- Descomposición de Servicios y Bounded Contexts
- API Gateway, Service Discovery y Comunicación entre Servicios
- Patrones de Resiliencia: Circuit Breaker, Retry y Bulkhead
- El Teorema CAP y la Consistencia de Datos
Módulo 5: Arquitecturas Dirigidas por Eventos y Mensajería
- Fundamentos de la Arquitectura Orientada a Eventos
- Mensajería Asíncrona: Colas y Brokers
- Patrones de Eventos: Event Sourcing y CQRS
- Gestión de Transacciones Distribuidas: Patrón Saga
- Streaming de Datos en Tiempo Real
Módulo 6: Diseño Dirigido por el Dominio (DDD)
- Conceptos Fundamentales del DDD
- Diseño Estratégico: Bounded Contexts y Lenguaje Ubicuo
- Diseño Táctico: Entidades, Agregados y Repositorios
- Mapeo de Contextos (Context Mapping)
Módulo 7: Datos y Persistencia
- Estrategias de Persistencia: SQL vs NoSQL
- Patrones de Acceso a Datos: Repository, Unit of Work y DAO
- Base de Datos por Servicio y Gestión de Datos Distribuidos
- Caché y Estrategias de Invalidación
Módulo 8: Arquitectura en la Nube y Despliegue
- Fundamentos del Cloud Computing (IaaS, PaaS, SaaS)
- Contenedores y Orquestación con Docker y Kubernetes
- Arquitectura Serverless
- Patrones de Diseño Cloud-Native
- Infraestructura como Código (IaC)
Módulo 9: Calidad, Seguridad y Observabilidad
- Escalabilidad: Horizontal vs Vertical y Balanceo de Carga
- Alta Disponibilidad y Tolerancia a Fallos
- Seguridad por Diseño y Autenticación/Autorización
- Observabilidad: Logging, Métricas y Trazabilidad
- Rendimiento y Pruebas de Carga
