Qué decide realmente una arquitectura
Una arquitectura no es un dibujo de cajas: es el conjunto de decisiones caras de revertir que condicionan cómo evoluciona un sistema. Cómo se parte en piezas, cómo se hablan esas piezas, dónde vive cada dato y qué se despliega junto con qué. Todo lo demás (el framework de moda, el nombre de las carpetas) se puede cambiar con un fin de semana; esto no.
Dos ideas ordenan todo lo que sigue:
- Cada estilo es una respuesta a un conjunto concreto de fuerzas. No hay estilos buenos y malos, hay estilos que encajan o no con el problema, el equipo y el momento.
- Toda decisión tiene un precio. Lo que un estilo mejora, otro atributo lo paga. El trabajo del arquitecto es hacer ese intercambio explícito y consciente.
Atributos de calidad: lo que de verdad elige la arquitectura
Los requisitos funcionales casi nunca deciden la arquitectura; los atributos de calidad sí. El modelo de calidad del producto de ISO/IEC 25010 sirve como lista de comprobación común:
| Característica | Pregunta que plantea |
|---|---|
| Adecuación funcional | ¿Hace lo que se necesita, de forma completa y correcta? |
| Eficiencia de desempeño | ¿Cuánto tarda, cuántos recursos consume, hasta dónde escala? |
| Compatibilidad | ¿Convive e intercambia información con otros sistemas? |
| Usabilidad | ¿Se aprende y se usa sin fricción? |
| Fiabilidad | ¿Madurez, disponibilidad, tolerancia a fallos, recuperación? |
| Seguridad | ¿Confidencialidad, integridad, trazabilidad, autenticidad? |
| Mantenibilidad | ¿Modularidad, reutilización, facilidad de análisis, de cambio y de prueba? |
| Portabilidad | ¿Se adapta, se instala y se sustituye con facilidad? |
Como en cualquier sistema real no caben todas al máximo, se priorizan. Un buen ejercicio es elegir las tres o cuatro que dominan y hacerlas medibles: «la búsqueda responde en menos de medio segundo para el percentil 95» es un requisito; «tiene que ser rápido» no lo es.
Escenarios de calidad
La forma más útil de concretar un atributo es el escenario: fuente del estímulo, estímulo, entorno, artefacto afectado, respuesta esperada y medida de la respuesta.
Fuente: usuarios finales
Estímulo: pico de tráfico al abrir una campaña
Entorno: funcionamiento normal
Artefacto: servicio de catálogo
Respuesta: sigue sirviendo páginas sin degradar el resto del sistema
Medida: tiempo de respuesta del percentil 95 dentro del objetivo acordadoCon escenarios escritos se puede comparar objetivamente dos alternativas y, más tarde, comprobar si la arquitectura los cumple.
Compromisos, leyes y principios que condicionan todo
Los compromisos clásicos
| Se gana | Se paga |
|---|---|
| Desacoplamiento entre piezas | Más comunicación, más fallos posibles en la red |
| Escalado independiente | Más infraestructura y más operación |
| Consistencia fuerte | Menos disponibilidad y más latencia al repartir datos |
| Flexibilidad y extensibilidad | Indirección y curva de aprendizaje |
| Despliegue independiente | Coordinación de contratos y versiones |
| Simplicidad operativa | Menos aislamiento de fallos |
Teorema CAP y modelo PACELC
En un sistema de datos distribuido, ante una partición de red hay que elegir entre consistencia (todos ven el mismo dato) y disponibilidad (todos reciben respuesta). Las particiones no se eligen: ocurren. Por eso la elección real es qué sacrificar cuando ocurren. PACELC lo completa: incluso sin partición hay que elegir entre latencia y consistencia. De ahí salen decisiones como replicación síncrona frente a asíncrona, o consistencia eventual aceptada de forma explícita en ciertos flujos.
Ley de Conway
Las organizaciones diseñan sistemas que copian su propia estructura de comunicación.
Se puede usar a favor (la maniobra inversa de Conway): se diseña primero la estructura de equipos que se quiere y la arquitectura tiende a seguirla. Una arquitectura en la que dos equipos deben coordinarse para cada cambio es síntoma de que las fronteras del código no coinciden con las del equipo.
Principios de diseño que se repiten en todos los estilos
- Alta cohesión, bajo acoplamiento dentro y entre módulos.
- Separación de responsabilidades: cada pieza tiene una razón principal para cambiar.
- Ocultar información: se expone un contrato estrecho y se esconde cómo está hecho por dentro.
- Dependencias hacia lo estable: lo que cambia poco no debe depender de lo que cambia mucho.
- Diseñar para el fallo: toda llamada que cruza una frontera puede fallar, tardar o duplicarse.
DDD estratégico: dónde poner las fronteras
Antes de elegir estilo hay que decidir qué se parte y por dónde. El diseño guiado por el dominio (DDD) aporta el vocabulario del lado estratégico:
- Lenguaje ubicuo: negocio y equipo técnico usan los mismos términos, y el código los refleja.
- Dominio y subdominios: el núcleo (lo que diferencia al negocio y merece más inversión), los de soporte (necesarios pero no diferenciales) y los genéricos (resueltos y comprables, como la facturación estándar o la autenticación).
- Contexto delimitado: el límite dentro del cual un modelo y un término tienen un significado único. «Cliente» en ventas y «cliente» en soporte pueden ser conceptos distintos y conviene que lo sean.
- Mapa de contextos: cómo se relacionan los contextos entre sí.
Relaciones habituales entre contextos:
| Relación | Significado |
|---|---|
| Cliente-proveedor | Un contexto aguas arriba sirve a otro aguas abajo, con necesidades negociadas |
| Conformista | El de abajo acepta el modelo del de arriba tal cual |
| Capa anticorrupción | El de abajo traduce el modelo ajeno para no contaminar el suyo |
| Servicio de lenguaje publicado | Un contrato público y estable que consumen muchos |
| Núcleo compartido | Un subconjunto del modelo que dos equipos mantienen juntos (se usa con cuidado) |
| Caminos separados | No se integran: cada uno resuelve lo suyo |
Un contexto delimitado es el candidato natural a módulo en un monolito modular y a servicio en microservicios. Partir por capas técnicas en lugar de por contextos suele producir sistemas donde cada cambio de negocio atraviesa todo.
Catálogo de estilos arquitectónicos
Para cada estilo: qué es, su flujo de trabajo y cuándo no conviene.
Monolito
Toda la aplicación, un único artefacto desplegable.
Flujo de trabajo: un repositorio, una compilación, una batería de pruebas y un despliegue. Un cambio se prueba entero y se publica entero. Depurar es sencillo porque todo ocurre en un proceso, y las transacciones son las de la base de datos.
Fortalezas: simplicidad, rendimiento de las llamadas internas, operación barata, refactorización asistida por el compilador.
Cuándo no usarlo: cuando muchos equipos se bloquean entre sí en el mismo despliegue, o cuando una parte necesita escalar o desplegarse con un ritmo radicalmente distinto al resto.
Monolito modular
Un solo despliegue, pero con módulos delimitados que se comunican únicamente por interfaces públicas.
Un solo proceso
Ningún módulo importa clases internas de otro.
Flujo de trabajo: se identifican los contextos delimitados y cada uno se convierte en un módulo con su API interna. Los datos se separan por esquema o por propietario, y las reglas de importación se comprueban automáticamente. Si algún día un módulo debe salir como servicio, la frontera ya existe.
Fortalezas: casi toda la ventaja organizativa de los microservicios con la operación de un monolito.
Cuándo no usarlo: si no hay disciplina para mantener las fronteras. Sin comprobación automática, los módulos acaban importándose entre sí y el resultado es un monolito enredado con otro nombre.
Arquitectura en capas (N-tier)
Se organiza el código por responsabilidad técnica: presentación, lógica, acceso a datos. Una capa solo conoce a la inferior.
Flujo de trabajo: una petición baja de la presentación a los datos y la respuesta sube por el mismo camino. Se distingue entre capas cerradas (solo se llama a la inmediatamente inferior) y abiertas (se puede saltar), y se documenta cuál es cuál.
Cuándo no usarlo: cuando las reglas de negocio son ricas y cambian mucho: acaban repartidas entre capas. Aparece también el antipatrón del «sumidero»: peticiones que atraviesan capas sin que ninguna aporte nada.
Cliente-servidor
Un servidor concentra la lógica y los datos; varios clientes los consumen por un protocolo común.
Clientes
Protocolo común, por ejemplo HTTP.
Flujo de trabajo: el contrato entre ambos se define primero; cliente y servidor evolucionan por separado mientras lo respeten. Es la base de casi todo lo demás: una web, una app móvil y una integración externa son clientes distintos de un mismo servidor.
Cuándo no usarlo: si los clientes necesitan funcionar sin conexión de forma prolongada, o si el servidor es un punto único de fallo intolerable. En esos casos se miran estrategias offline-first o sin punto central.
Hexagonal (puertos y adaptadores)
El dominio define los puertos (interfaces que necesita) y la infraestructura los implementa con adaptadores. Protege la lógica de negocio de la tecnología.
Adaptadores de entrada
Adaptadores de salida
Flujo de trabajo: se escribe primero el dominio con sus pruebas, usando adaptadores falsos en memoria. Después se añaden los adaptadores reales (base de datos, cola, API externa) y se comprueba que cumplen el puerto. Cambiar de base de datos o de proveedor no toca las reglas.
Cuándo no usarlo: en un CRUD sencillo sin lógica real: añade interfaces y traducciones sin beneficio.
Arquitectura limpia (onion)
Variante concéntrica del mismo principio: la regla de dependencia exige que el código fuente solo apunte hacia el centro.
Capa exterior
El centro no conoce nada de lo que tiene alrededor.
Flujo de trabajo: se parte de las entidades y los casos de uso; el exterior (web, persistencia, interfaz) se enchufa al final. Los datos que cruzan una frontera lo hacen en estructuras simples, no en objetos del framework.
Cuándo no usarlo: igual que la hexagonal: si el dominio no justifica las capas. Un riesgo frecuente es duplicar clases en cada anillo solo por cumplir el esquema.
Microservicios
Servicios pequeños, desplegables por separado, cada uno dueño de sus datos y alineado con un contexto delimitado.
Flujo de trabajo: cada equipo tiene su repositorio o su carpeta, su canal de integración continua y su ritmo de despliegue. Los servicios se hablan por contratos versionados. Requieren, como base, automatización completa de despliegue, observabilidad distribuida (trazas, métricas, registros correlados) y una estrategia para la consistencia entre servicios.
Cuándo no usarlo: con un equipo pequeño, un dominio todavía inestable o sin automatización. El síntoma de haberlo hecho mal es el monolito distribuido: servicios que hay que desplegar juntos y se llaman en cadena síncrona.
Orientada a eventos
Los componentes no se invocan: publican hechos y otros reaccionan a ellos.
Flujo de trabajo: el productor publica un evento ya ocurrido («pedido confirmado») sin saber quién lo consume. Añadir una funcionalidad es añadir un consumidor. Hay dos modelos: broker (descentralizado, cada consumidor reacciona) y mediador (un orquestador central coordina el flujo).
Cuándo no usarlo: cuando se necesita una respuesta inmediata y consistente, o cuando el flujo es tan lineal que seguirlo a través de eventos solo lo hace opaco. El coste está en la depuración y en la consistencia eventual.
Event sourcing
En lugar de guardar el estado actual, se guarda la secuencia de eventos que lo produjo. El estado se reconstruye reproduciéndolos.
Suscriptores
Flujo de trabajo: un comando llega a un agregado, que valida las reglas y emite eventos; estos se añaden al registro y las proyecciones los consumen para construir las vistas. Para no reproducir toda la historia se guardan instantáneas periódicas. Los cambios de esquema de eventos se gestionan con versionado de eventos.
Fortalezas: auditoría completa, posibilidad de reconstruir el estado en cualquier instante, nuevas proyecciones sobre datos antiguos.
Cuándo no usarlo: casi siempre que no haya una necesidad clara de historia o auditoría. Es de los estilos más caros de entender, de migrar y de corregir (un error ya registrado se compensa, no se borra).
CQRS
Separa el modelo que escribe del que lee. Suele acompañar a event sourcing, pero no lo exige.
Cliente
Los eventos del modelo de escritura actualizan las vistas, con cierta demora.
Flujo de trabajo: los comandos pasan por el modelo de escritura, que protege las invariantes; sus cambios se propagan a modelos de lectura optimizados para cada consulta. Las lecturas pueden ir a un almacén distinto, con la forma exacta que necesita la pantalla.
Cuándo no usarlo: si lectura y escritura tienen formas parecidas y cargas similares. Sumar dos modelos y la sincronización entre ellos es complejidad sin retorno.
Serverless (funciones como servicio)
Funciones que se ejecutan bajo demanda sobre infraestructura gestionada por el proveedor.
Disparadores
Servicios gestionados
Flujo de trabajo: cada función se despliega por separado y responde a un disparador (petición, evento, temporizador). No hay servidores que mantener y el coste sigue al uso. La lógica se escribe sin estado; el estado vive en servicios gestionados.
Cuándo no usarlo: procesos largos, latencia muy exigente donde el arranque en frío molesta, cargas constantes y altas donde un servidor propio sale más barato, o cuando el riesgo de dependencia del proveedor no es asumible.
Pipes and filters
Cadena de pasos independientes: cada filtro transforma la entrada y entrega su salida al siguiente.
Cada filtro hace una sola cosa
Los filtros se pueden reordenar, sustituir o paralelizar.
Flujo de trabajo: se descompone el procesamiento en pasos con una sola responsabilidad y un formato de intercambio común. Cada filtro se prueba aislado y se puede reordenar, sustituir o ejecutar en paralelo. Es la forma natural de las canalizaciones de datos, los compiladores y las tuberías de Unix.
Cuándo no usarlo: cuando los pasos necesitan mucho contexto compartido o interacción entre sí, o cuando el trabajo es interactivo y no por lotes.
Microkernel (plugins)
Un núcleo pequeño y estable con las funciones mínimas, y extensiones que se enchufan a través de un contrato.
Extensiones
Flujo de trabajo: se define el contrato de los plugins (interfaz, ciclo de vida, descubrimiento) y se mantiene estable; las funcionalidades nuevas se escriben como plugins, a veces por terceros. Los editores de código y los navegadores usan este modelo.
Cuándo no usarlo: si no hay una necesidad real de extensión de terceros o de variantes por cliente. Un contrato de plugins mal pensado es difícil de cambiar sin romper el ecosistema.
Space-based
Pensada para escalar picos extremos: la lógica y los datos viven en memoria distribuida y la base de datos se actualiza de forma asíncrona.
Flujo de trabajo: las peticiones llegan a unidades de proceso que operan sobre su copia de los datos en la rejilla; la rejilla replica entre unidades y un proceso en segundo plano persiste los cambios. Se añaden o se retiran unidades según la carga.
Cuándo no usarlo: cuando los datos son enormes (no caben en memoria), cuando se exige consistencia fuerte inmediata o cuando la carga es estable y no justifica la complejidad.
SOA (arquitectura orientada a servicios)
Servicios de negocio reutilizables, tradicionalmente coordinados por un bus de servicios empresarial que enruta, transforma y orquesta.
Consumidores
Flujo de trabajo: se identifican servicios de granularidad empresarial, se publican sus contratos y el bus encadena las llamadas entre sistemas heterogéneos. Es el antecesor de los microservicios, con servicios más grandes, esquemas compartidos y lógica en el bus.
Cuándo no usarlo: el bus central tiende a convertirse en un cuello de botella y un punto de acoplamiento organizativo. Hoy se prefieren extremos inteligentes y conductos sencillos.
Peer-to-peer
No hay un servidor central: cada nodo es cliente y servidor a la vez.
Cada nodo se conecta con varios vecinos; el sistema sigue si uno cae.
Flujo de trabajo: los nodos se descubren entre sí, intercambian datos directamente y se reparten la carga. Es el modelo de distribución de ficheros, de ciertos sistemas de mensajería y de las redes de cadena de bloques.
Cuándo no usarlo: si se necesita control central, autoridad sobre los datos o garantías de consistencia fuertes. La seguridad y la confianza entre nodos son el gran reto.
Comparativa de estilos
| Estilo | Despliegue | Escala | Complejidad operativa | Cambio en una parte |
|---|---|---|---|---|
| Monolito | Uno | Todo a la vez | Baja | Redespliega todo |
| Monolito modular | Uno | Todo a la vez | Baja | Redespliega todo, cambio localizado |
| Capas | Normalmente uno | Por capa si se separan | Baja | Suele cruzar capas |
| Hexagonal / limpia | Uno o varios | Según despliegue | Baja a media | Aislado en adaptadores |
| Microservicios | Muchos | Por servicio | Alta | Un servicio |
| Eventos | Varios | Por consumidor | Media a alta | Un consumidor |
| Event sourcing y CQRS | Varios | Lectura y escritura por separado | Alta | Proyecciones nuevas sin tocar el origen |
| Serverless | Por función | Automática | Media (cambia de sitio) | Una función |
| Microkernel | Núcleo más plugins | Del núcleo | Media | Un plugin |
| Space-based | Muchas unidades | Muy alta, elástica | Muy alta | Compleja |
Patrones de integración y resiliencia
Cuando el sistema se reparte en piezas que se hablan por red, aparecen problemas propios con soluciones conocidas.
API gateway
Un único punto de entrada para los clientes que resuelve lo transversal.
Concentra autenticación, límites de uso, enrutado y, a veces, la agregación de varias respuestas. Evita que cada servicio repita esa lógica. Riesgo: convertirse en un monolito de reglas de negocio; el gateway debe quedarse en lo transversal.
Saga
Una transacción de negocio que abarca varios servicios no puede apoyarse en una transacción de base de datos. La saga la divide en pasos locales, cada uno con una acción compensatoria que lo deshace.
Si el cobro falla, se compensa hacia atrás: liberar stock y cancelar pedido.
Hay dos formas: coreografía (cada servicio reacciona a los eventos del anterior, sin coordinador) y orquestación (un orquestador dice qué paso toca). La coreografía es más desacoplada pero más difícil de seguir; la orquestación es más legible y centraliza el estado. Los pasos y compensaciones deben ser idempotentes.
Outbox transaccional
Resuelve el problema de la doble escritura: guardar en la base de datos y publicar un evento sin que uno se pierda si el otro falla.
Entrega al menos una vez: los consumidores deben tolerar duplicados.
El evento se escribe en una tabla de la misma transacción que el cambio de estado; un proceso aparte lo lee y lo publica. La entrega resultante es al menos una vez, de modo que el consumidor debe ser idempotente (por ejemplo, descartando identificadores de evento ya procesados). Es el complemento imprescindible de cualquier arquitectura de eventos seria.
Circuit breaker
Evita que un servicio que falla arrastre a quien lo llama.
Se abre al superar un umbral de fallos.
Si responden bien, vuelve a cerrado; si no, a abierto.
Si las llamadas fallan por encima de un umbral, el circuito se abre y las siguientes fallan al instante sin esperar. Pasado un tiempo, se dejan pasar unas pocas de prueba. Se combina con timeouts explícitos, reintentos con espera creciente y aleatoria (nunca reintentos inmediatos y masivos), bulkheads (compartimentos de recursos separados) y un camino degradado definido.
Strangler fig
La forma segura de sustituir un sistema antiguo sin una reescritura total.
Una fachada se coloca delante; cada funcionalidad se reimplementa en el sistema nuevo y la fachada empieza a enrutarle esa parte. El sistema viejo se va vaciando hasta poder apagarlo. El valor está en que cada paso es pequeño, desplegable y reversible.
Otros patrones que conviene conocer
| Patrón | Problema que resuelve |
|---|---|
| Capa anticorrupción | Evitar que el modelo de un sistema ajeno contamine el propio |
| Backend for frontend | Cada tipo de cliente tiene una API adaptada a sus necesidades |
| Sidecar | Añadir capacidades transversales (observabilidad, seguridad) junto a cada servicio |
| Cache-aside | Acelerar lecturas sin que la caché sea la fuente de verdad |
| Idempotent consumer | Procesar un mensaje repetido sin efectos duplicados |
| Bulkhead | Aislar recursos para que un fallo no consuma todos |
Datos y consistencia
La decisión más difícil de revertir casi siempre es la de los datos.
- Un dueño por dato: cada dato tiene un único servicio o módulo responsable de escribirlo. Los demás lo piden o guardan una copia derivada.
- No compartir tablas entre servicios: una base de datos compartida es una API sin contrato y acopla los despliegues.
- Consistencia fuerte frente a eventual: la fuerte es más simple de razonar; la eventual escala mejor y exige diseñar la interfaz y las reglas para tolerar el desfase.
- Transacciones distribuidas: el compromiso en dos fases es frágil y lento; se suele preferir saga más outbox.
- Migraciones: los cambios de esquema se hacen en pasos compatibles hacia atrás (expandir, migrar, contraer) para poder desplegar sin parar.
Cómo se decide una arquitectura
- Entender el contexto: objetivos de negocio, restricciones (presupuesto, plazo, equipo, normativa) y atributos de calidad prioritarios, con escenarios medibles.
- Generar alternativas: al menos dos. Una decisión con una sola opción no es una decisión.
- Evaluar los compromisos: qué gana y qué paga cada opción frente a los escenarios. Para decisiones de gran riesgo sirve un método estructurado de evaluación por escenarios como ATAM.
- Probar lo que más riesgo tiene: una prueba de concepto o un spike sobre la hipótesis más dudosa, no sobre lo fácil.
- Registrar la decisión en un ADR.
- Vigilar que se cumple con comprobaciones automáticas.
- Revisar cuando cambien los requisitos, no por inercia ni por moda.
ADR: registros de decisiones de arquitectura
Un ADR es un documento corto, inmutable una vez aceptado y guardado junto al código. Si una decisión cambia, se escribe un ADR nuevo que sustituye al anterior.
## ADR-007: Separar el módulo de facturación como servicio
Estado: aceptada
Contexto: facturación se despliega con un ritmo distinto y tiene
requisitos normativos propios; hoy bloquea los despliegues del resto.
Decisión: extraer facturación como servicio con su propia base de datos.
Alternativas descartadas:
- Mantenerla como módulo: no resuelve el bloqueo de despliegues.
- Reescribirla desde cero: riesgo y plazo desproporcionados.
Consecuencias:
- Más: despliegue independiente y datos aislados.
- Menos: consistencia eventual con pedidos, necesidad de saga.Fitness functions
Una fitness function es una comprobación automática de que una característica de la arquitectura sigue cumpliéndose. Convierte las decisiones en reglas ejecutables:
- Una regla que falla la compilación si el dominio importa algo de infraestructura.
- Un test que detecta dependencias cíclicas entre módulos.
- Una prueba de carga en integración continua que alerta si un tiempo de respuesta se degrada.
- Un límite al tamaño o a la complejidad de un módulo.
Sin esto, la arquitectura documentada y la real se separan poco a poco.
Cómo se documenta
- Modelo C4: cuatro niveles de zoom: contexto del sistema, contenedores, componentes y código. Cada diagrama responde a una pregunta y tiene un público.
- Vistas por interesado: quien opera necesita una vista de despliegue; quien desarrolla, de módulos; quien decide, de contexto.
- Documentación junto al código, versionada con él, y diagramas generados o fáciles de editar.
- Qué no documentar: lo que el código ya dice con claridad. Se documentan las razones y las fronteras.
Evolución de una arquitectura
Una arquitectura no se acaba: se hace evolucionar.
- Empezar simple. Un monolito modular bien delimitado cubre mucho más tiempo del que se cree.
- Medir antes de partir. Se separa una pieza cuando hay una razón observable: ritmo de cambio distinto, escalado distinto, equipo distinto, requisito de aislamiento.
- Extraer por el borde. Primero los módulos con menos dependencias; se usa el strangler fig y se mantiene la compatibilidad.
- Cambios compatibles en pasos pequeños. Cada paso es desplegable y reversible.
- Limpiar lo que queda. Apagar de verdad el código y los datos antiguos; lo que se deja «por si acaso» se convierte en deuda.
- Reevaluar las decisiones a la luz de lo aprendido, con nuevos ADR.
Lista de comprobación antes de dar por buena una arquitectura
- Los atributos de calidad prioritarios están escritos como escenarios medibles.
- Cada decisión importante tiene su ADR con alternativas descartadas.
- Las fronteras coinciden con contextos del dominio y con equipos.
- Cada dato tiene un único dueño.
- Toda llamada entre piezas tiene tiempo máximo, política de reintentos y comportamiento degradado.
- Se puede desplegar y volver atrás sin intervención manual.
- Hay trazas, métricas y registros correlados para seguir una petición de extremo a extremo.
- Las reglas de dependencia se comprueban en integración continua.
- Se sabe qué ocurre si cae cada dependencia externa.
Antipatrones habituales
- Microservicios por moda: adoptar la complejidad de lo distribuido sin tener el problema que resuelve.
- Monolito distribuido: servicios acoplados que se despliegan juntos y se llaman en cadena síncrona.
- Base de datos compartida: varios servicios leyendo y escribiendo las mismas tablas.
- Gran bola de barro: sin estructura reconocible, cualquier cosa depende de cualquier cosa.
- Arquitectura de ensueño: diseñar para una escala o una variabilidad que nunca llega.
- Dios servicio o dios módulo: una pieza que lo sabe y lo hace todo.
- Golden hammer: usar siempre la misma tecnología o estilo, sea cual sea el problema.
- Resume-driven design: elegir tecnologías por lo que aportan al currículo y no al sistema.
- Decisiones sin registro: las razones solo viven en la cabeza de quien las tomó.
- Ignorar la organización: diseñar fronteras que contradicen la estructura de los equipos.