Estilos arquitectónicos y criterios de elección | Nicolás Garzón
Un estilo arquitectónico define una familia de estructuras, restricciones y formas de colaboración. Elegir uno no consiste en seleccionar el patrón más prestigioso, sino en comprobar qué drivers satisface y qué costos introduce.
Los estilos ayudan a razonar sobre la forma global de un sistema:
Cómo se dividen responsabilidades.
Cómo se comunican las partes.
Dónde vive el estado.
Qué dependencias están permitidas.
Cómo se despliega y opera.
Un sistema real puede combinar estilos en escalas distintas.
Texto
Copiar sistema: monolito modular
módulo: arquitectura hexagonal
procesamiento: pipe and filter
eventos: integración asíncrona selectivaSin un vocabulario estructural, el equipo toma decisiones aisladas que pueden contradecirse. Un estilo ofrece restricciones conocidas y trade-offs estudiados.
El error aparece cuando se adopta como receta universal. “Microservicios”, “event-driven” o “Clean” no son niveles de madurez.
Organiza por niveles de abstracción.
Texto
Copiar presentation → application → domain → infrastructure
Flujo comprensible.
Separación de responsabilidades.
Adecuada para aplicaciones con interacción request/response.
Capas ceremoniales.
Estructura global por tipo técnico.
Dominio anémico.
Funciona mejor combinada con módulos o vertical slices.
Protegen un núcleo mediante inversión de dependencias.
Independencia de mecanismos.
Testabilidad.
Fronteras explícitas.
Contratos y mapeos.
Mayor navegación.
Abstracciones innecesarias si el dominio es simple.
Una unidad de despliegue con módulos fuertes por capacidad.
Transacciones locales.
Desarrollo y debugging sencillos.
Menor carga operativa.
Seams de extracción futura.
Escalado conjunto.
Despliegue global.
Riesgo de erosión de límites.
Requiere reglas de dependencia y ownership, no solo carpetas.
Servicios desplegables de forma independiente, alineados con capacidades y datos propios.
Autonomía potencial de equipos.
Escalado y despliegue independientes.
Aislamiento tecnológico u operativo.
Red y fallos parciales.
Consistencia eventual.
Contratos y observabilidad distribuida.
CI/CD, seguridad y on-call por servicio.
No aportan autonomía si cada cambio exige coordinación.
Productores publican hechos y consumidores reaccionan.
Desacoplamiento temporal.
Fan-out.
Procesamiento asíncrono.
Duplicados y desorden.
Flujos implícitos.
Debugging y schema evolution.
Conviene para reacciones y propagación; no para cada colaboración local.
Procesamiento dividido en transformaciones encadenadas:
Texto
Copiar input → validate → normalize → enrich → persist
Composición.
Reutilización.
Paralelismo potencial.
Serialización y movimiento de datos.
Diagnóstico del estado intermedio.
Manejo de errores parciales.
Adecuado para ETL, compiladores y procesamiento de medios.
Un núcleo estable carga capacidades extensibles.
Texto
Copiar core
├── plugin ventas
├── plugin facturación
└── plugin reportes
Extensibilidad.
Producto base estable.
Variantes por cliente.
Contrato de plugins duradero.
Compatibilidad y aislamiento.
Debugging de combinaciones.
Un mediador conecta y enruta componentes. Brokers de mensajes, RPC o integración reducen conocimiento de ubicación, pero se convierten en infraestructura crítica.
Distribuye estado y procesamiento en memoria para evitar un cuello central bajo cargas extremas. Aporta escalado, pero exige particionamiento, consistencia, recuperación y operación avanzada. Es una respuesta especializada, no una arquitectura inicial común.
Unidad de ejecución administrada por plataforma y activada por eventos.
Escalado administrado.
Pago por uso en ciertos perfiles.
Menor gestión de servidores.
Límites de runtime.
Cold starts.
Observabilidad fragmentada.
Lock-in y costos variables.
Estado externo obligatorio.
Es un modelo operativo que puede combinarse con otros estilos.
¿Qué cualidades son prioritarias?
¿Los límites son conocidos o todavía cambian?
¿Existe necesidad real de autonomía y ownership?
¿El equipo puede manejar red, brokers, trazas, recuperación y múltiples pipelines?
¿Puede comenzarse con una opción simple que conserve seams?
¿Qué carga, fallos o cambios justifican la complejidad?
Texto
Copiar DomiSys inicial
equipo: pequeño
dominio: en evolución
transacciones: importantes
escala: moderada
operación distribuida: limitada
opción coherente:
monolito modular + capas/hexagonal dentro de módulos
+ eventos internos selectivosMicroservicios podrían aparecer después si existen equipos, escala o aislamiento diferenciados.
Los estilos operan en escalas distintas:
Módulo de Pedidos: Clean/Hexagonal.
Aplicación completa: monolito modular.
Notificaciones: event-driven.
Importación de datos: pipe and filter.
Integración de pagos: adapter.
La combinación debe conservar un modelo mental comprensible. Mezclar estilos sin límites claros produce complejidad accidental.
Independencia total, consistencia fuerte y latencia mínima entre regiones no pueden maximizarse simultáneamente. Prioriza escenarios.
Puede ser válido por aislamiento regulatorio o cargas muy distintas, pero el costo debe estar respaldado.
Una unidad de despliegue puede escalar horizontalmente. Escala no implica automáticamente servicios.
Puede aumentar riesgo de seguridad y combinaciones. Considera configuración y feature flags antes de código arbitrario.
Arquitectura por moda.
Estilo por tamaño de empresa ajena.
Un servicio por entidad.
Eventos para llamadas locales simples.
Capas vacías.
Mezclar estilos sin ownership.
Ignorar capacidad operativa.
Diseñar para volumen hipotético.
Escenarios de calidad.
Pruebas de concepto.
Simulaciones de cambio.
Pruebas de carga y fallo.
Evaluación de costo operativo.
ADR con señales de revisión.
Fitness functions.
Un estilo es un conjunto de restricciones y trade-offs.
No existe un estilo universalmente superior.
Los sistemas combinan estilos en escalas distintas.
La topología del equipo y capacidad operativa importan.
La alternativa mínima que satisface drivers suele conservar más opciones.
¿Por qué microservicios no son una etapa obligatoria?
¿Cuándo usarías pipe and filter?
¿Qué diferencia existe entre serverless y event-driven?
¿Cómo combinarías monolito modular y hexagonal?
¿Qué evidencia justificaría space-based?
Monolito modular, microservicios y arquitectura evolutiva profundiza en la decisión de topología y en cómo migrarla sin convertirla en una apuesta irreversible.