Hay una conversación que se repite en muchos equipos. Alguien en una revisión dice "acá conviene un adapter", otra persona entiende "puertos y adaptadores", y durante diez minutos cada uno defiende algo distinto creyendo que hablan de lo mismo. No es un problema de inteligencia. Es un problema de vocabulario: usamos la palabra "patrón" para cosas que viven en escalas muy diferentes.

Este post es para ordenar ese vocabulario. Está pensado para quien va partiendo, y también para el PO, QA u operaciones, que escuchan estas palabras en cada reunión sin que nadie se las haya explicado con calma.

Primero, ¿qué es un patrón?

Un patrón es una solución con nombre a un problema que se repite en cierto contexto. No es código para copiar y pegar: es una forma de pensar una solución, con sus ventajas y sus costos.

La idea viene de la arquitectura de edificios (Christopher Alexander) y llegó al software con fuerza en 1994, cuando Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides publicaron Design Patterns: Elements of Reusable Object-Oriented Software, el famoso libro de la "pandilla de los cuatro" o GoF, con 23 patrones que todavía se enseñan.

Con los años aparecieron patrones de otra escala: ya no sobre cómo se organizan unas pocas clases, sino sobre cómo se organiza un sistema completo. Ahí está la diferencia que importa.

Dos escalas: la ciudad y el edificio

La metáfora que más me sirve es la de una ciudad. Los patrones arquitectónicos son el plano regulador: dónde van las avenidas, qué barrios se conectan, por dónde pasa el agua. Los patrones de diseño son las soluciones dentro de cada edificio: cómo se distribuyen las piezas, dónde va la escalera.

Mover una escalera es molesto, pero se puede hacer en un fin de semana. Mover una avenida es otra historia.

Patrones de diseño (GoF y similares). Resuelven problemas dentro del código de un componente. Algunos ejemplos:

  • Strategy: tener varias formas intercambiables de hacer lo mismo. Por ejemplo, calcular la comisión de una transferencia según sea a otro banco, al mismo banco o internacional, sin llenar el código de if.
  • Observer: avisar a varios interesados cuando algo cambia, sin que el objeto que cambia sepa quiénes son.
  • Factory: centralizar la creación de objetos. Por ejemplo, crear el procesador correcto según el tipo de tarjeta.
  • Adapter: envolver una interfaz que no calza con la que necesitas, como una librería antigua que devuelve los montos en un formato distinto.

Patrones arquitectónicos. Resuelven cómo se reparte un sistema en piezas, cómo se comunican y dónde viven los datos. Algunos ejemplos:

  • Capas: presentación, negocio y datos, cada una hablando solo con la de abajo.
  • Hexagonal o puertos y adaptadores: el negocio al centro y la tecnología (bases de datos, colas, APIs) en los bordes.
  • Monolito modular y microservicios: un solo despliegue bien dividido por dentro, o muchos servicios desplegados por separado.
  • Event-driven: los componentes se comunican publicando hechos ("se aprobó el crédito") en vez de llamarse directamente.
  • CQRS y event sourcing: separar el modelo de escritura del de lectura, y guardar la historia de eventos en lugar de solo el estado actual.
  • Saga, API gateway y strangler fig: coordinar transacciones entre servicios, poner una puerta de entrada única y reemplazar un sistema antiguo de a poco.

Martin Fowler, en su guía de arquitectura, recoge una idea de Ralph Johnson (sí, uno de los cuatro del GoF) que me encanta: la arquitectura no es tanto "lo de alto nivel" como el entendimiento compartido que tienen los desarrolladores expertos sobre el diseño del sistema, y las decisiones que uno quisiera haber tomado bien desde el principio. En otras palabras: las decisiones caras de revertir.

La tabla para tener a mano

DimensiónPatrón de diseñoPatrón arquitectónico
AlcanceUnas pocas clases u objetosEl sistema completo o varios sistemas
Pregunta que responde¿Cómo organizo este código?¿Cómo divido el sistema y cómo se comunican sus partes?
Costo de cambiarloBajo: un refactor de horas o díasAlto: meses, migraciones de datos, coordinación entre equipos
Quién lo notaQuien lee y mantiene el códigoTodo el equipo, operaciones, seguridad y a veces el cliente
AfectaLegibilidad, extensibilidad, testeoEscalabilidad, disponibilidad, seguridad, costos, organización de equipos
EjemplosStrategy, Observer, Factory, AdapterCapas, hexagonal, microservicios, CQRS, saga
Dónde se documentaEn el código y en la revisión del PREn diagramas y registros de decisiones (ADR)

El mismo nombre en dos niveles

Lo que más confunde, y a la vez lo más bonito, es que muchas ideas se repiten en ambas escalas.

Adapter y puertos y adaptadores. El adapter del GoF envuelve una clase para que calce con otra interfaz. La arquitectura hexagonal de Alistair Cockburn toma esa misma intuición y la lleva a todo el sistema: el núcleo de negocio define "puertos" (lo que necesita, por ejemplo "consultar saldo") y cada tecnología se conecta mediante un "adaptador". Cockburn lo planteó para que una aplicación pueda ser usada igual por personas, por otros programas o por pruebas automáticas, y probarse sin depender de la base de datos real. En la práctica, cada adaptador hexagonal suele estar implementado con un adapter GoF. Misma idea, dos zooms.

Observer y event-driven. El observer avisa a otros objetos dentro de un mismo proceso. La arquitectura orientada a eventos hace lo mismo entre sistemas, con un broker de mensajes al medio. La diferencia es enorme en la práctica: entre procesos aparecen la red, los mensajes duplicados, el orden y la consistencia eventual. Fowler muestra que "event-driven" agrupa varios patrones distintos y conviene saber cuál usas.

Veámoslo en un ejemplo de pagos:

flowchart LR APP[App móvil] --> GW[API Gateway] subgraph SVC[Servicio de transferencias - hexagonal] direction TB PIN[Puerto de entrada<br/>Transferir] --> NUC[Núcleo de negocio<br/>Strategy: cálculo de comisión] NUC --> POUT1[Puerto: Cuentas] NUC --> POUT2[Puerto: Eventos] end GW --> PIN POUT1 --> AD1[Adaptador del core bancario<br/>Adapter GoF sobre la API antigua] POUT2 --> BRK[(Broker de mensajes)] BRK --> NOT[Notificaciones] BRK --> CON[Contabilidad] BRK --> FRA[Antifraude]

El API gateway, la estructura hexagonal y el broker son decisiones arquitectónicas: cambiarlas toca a varios equipos. El strategy de comisiones y el adapter sobre la API del core son decisiones de diseño: se pueden rehacer en un sprint sin que nadie fuera del equipo se entere.

Los patrones arquitectónicos también cobran

Un junior suele ver los patrones como trofeos: mientras más, mejor. Es al revés. Cada patrón arquitectónico trae una cuenta que se paga todos los meses.

  • Los microservicios dan despliegues independientes, pero traen red, observabilidad distribuida y datos repartidos. Por eso Fowler sugiere partir con un monolito primero y dividir cuando los límites estén claros.
  • Si una transferencia toca varios servicios, ya no hay un COMMIT único. La saga resuelve esto con una secuencia de transacciones locales y acciones de compensación (si falla el abono, se revierte el cargo). Funciona, pero hay que diseñar cada compensación y probarla.
  • CQRS puede ser muy útil, por ejemplo para separar el registro de movimientos de las consultas de cartola. Pero el propio Fowler advierte que para la mayoría de los sistemas agrega una complejidad riesgosa.
  • Event sourcing calza naturalmente con la contabilidad, que siempre ha sido un registro de hechos, pero exige pensar en cómo versionar eventos y reconstruir estados.
  • El strangler fig permite reemplazar un core antiguo funcionalidad por funcionalidad, en vez de apostar todo a un gran reemplazo de una noche.

Por qué todo el equipo debería conocerlos

Aquí está el punto central del post. Conocer estos patrones no es un tema de cargo; es un tema de poder conversar.

Desarrolladores. Un vocabulario común acorta las revisiones de código y diseño. Decir "esto rompe la regla de dependencias de la hexagonal" ahorra un párrafo.

QA. Si el sistema usa eventos y consistencia eventual, el saldo puede tardar unos segundos en verse actualizado y eso no es un bug. Si hay sagas, los casos de prueba más importantes son las compensaciones: ¿qué pasa si el abono falla después del cargo? La arquitectura hexagonal, además, facilita probar el negocio sin la base de datos real.

Product owners. Entender los trade-offs ayuda a estimar y priorizar. Una funcionalidad que cruza tres servicios no cuesta lo mismo que una que vive dentro de uno. Y saber qué es un strangler fig permite planificar una modernización en entregas de valor, no en un "big bang".

Operaciones y SRE. Cada patrón cambia cómo se depura un incidente. En un monolito, el stack trace cuenta la historia; en microservicios necesitas trazas distribuidas e identificadores de correlación. Saber dónde hay colas y reintentos acorta mucho la búsqueda de la causa.

Seguridad. Un API gateway centraliza autenticación y límites de tráfico; un broker de eventos es un lugar donde viajan datos sensibles que hay que cifrar y controlar. Cada patrón mueve la superficie de ataque.

Y para todos: los patrones ayudan a prevenir deuda técnica. La mayor parte de la deuda cara no nace de un for mal escrito, sino de una decisión arquitectónica tomada sin entender sus costos, o de no saber que existía una alternativa con nombre.

Cómo empezar a aprenderlos

Una ruta práctica:

  1. Parte por los patrones de diseño más comunes. Strategy, Observer, Factory, Adapter, Decorator y Template Method cubren mucho. El libro del GoF es la fuente original, aunque es denso; una buena alternativa es leerlo de a un patrón, con un ejemplo en tu lenguaje.
  2. Busca los patrones en el código que ya tienes. Tu framework está lleno de ellos. Ponerles nombre en el código real fija mucho más que cualquier ejemplo de libro.
  3. Pasa a los estilos de arquitectura. El catálogo de estilos del Azure Architecture Center compara capas, microservicios, event-driven y otros con sus beneficios y desafíos. Su catálogo de patrones cloud sirve para la siguiente etapa.
  4. Profundiza en sistemas distribuidos. microservices.io, de Chris Richardson, ordena saga, API gateway y compañía en un lenguaje de patrones conectado.
  5. Dibuja el sistema donde trabajas. Un diagrama simple: qué piezas hay, cómo se hablan, dónde están los datos. Luego pregunta qué patrones se usaron y por qué.
  6. Lee y escribe decisiones. Los registros de decisiones de arquitectura (ADR) muestran el contexto y los trade-offs de cada elección. Leer los de tu equipo, o proponer el primero, es la mejor escuela.

En 20+ años de experiencia he visto pasar muchas modas, pero los buenos patrones siguen vigentes porque no son modas: son nombres para problemas que no se van. Aprender ese idioma no te convierte en arquitecto de la noche a la mañana, pero sí te sienta en la mesa donde se toman las decisiones que más cuestan cambiar.

Lecturas recomendadas

Si este post te dejó con ganas de seguir, esta es la ruta que yo usaría: de lo más amable a lo más exigente.

Libros

  • Head First Design Patterns, 2.ª edición (Eric Freeman y Elisabeth Robson, O'Reilly). La puerta de entrada. Si strategy, observer o adapter todavía se te mezclan, aquí se explican con calma y con ejemplos, antes de pasar al libro denso.

  • Design Patterns: Elements of Reusable Object-Oriented Software (Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides, Addison-Wesley). El clásico de la pandilla de los cuatro. Yo lo leería de a un patrón, con el código de tu proyecto al lado: es la fuente, y no pretende ser fácil.

  • Fundamentals of Software Architecture, 2.ª edición (Mark Richards y Neal Ford, O'Reilly). El puente entre escribir código y decidir arquitectura. Sirve para nombrar estilos, características y costos de una decisión sin convertir la conversación en una moda.

  • Patterns of Enterprise Application Architecture (Martin Fowler). El catálogo de lo que ya vive en casi todo sistema de negocio: cómo partes las capas, dónde pones la lógica y cómo la conversas con una base de datos.

  • Pattern-Oriented Software Architecture, volumen 1 (Frank Buschmann y colegas, Wiley). El POSA. Aquí los patrones dejan de ser fichas sueltas y se ordenan en un sistema, desde la forma del sistema hasta el idioma del código.

  • Domain-Driven Design: Tackling Complexity in the Heart of Software (Eric Evans, Addison-Wesley). Para cuando el negocio es más difícil que el framework. Deja un lenguaje para partir el dominio y hacer que ese modelo mande en el diseño.

  • Enterprise Integration Patterns (Gregor Hohpe y Bobby Woolf, Addison-Wesley). El vocabulario de los mensajes. Lo abro cuando dos sistemas tienen que hablarse y una llamada directa ya no alcanza.

  • Microservices Patterns (Chris Richardson, Manning). Para quien está decidiendo si parte el sistema, o ya lo partió y está pagando el costo. Ahí están la descomposición, las sagas y las consultas, con las dificultades incluidas.

  • Software Architecture: The Hard Parts (Neal Ford, Mark Richards, Pramod Sadalage y Zhamak Dehghani, O'Reilly). Sirve cuando no hay una práctica que te saque del problema: granularidad de servicios, datos y transacciones repartidas. Ayuda a ver los dos lados antes de elegir.

  • Designing Data-Intensive Applications (Martin Kleppmann, O'Reilly). El más exigente de la lista. Cuando la pregunta ya no es cómo se llama el patrón, sino qué pasa con los datos si se replican, se atrasan o se caen.

Sitios web