Todos los artículos
Engineering

Design patterns que de verdad importan (con ejemplos en Java)

No los 23 patrones del Gang of Four recitados de memoria: los cinco que usamos de verdad en producción, ejemplos en Java, cuándo aplicar un patrón es la decisión equivocada y por qué las entrevistas siguen preguntando por ellos.

Michele Cimmino · CEO & Academy Director, Lasting Dynamics · 25 de agosto de 2026 · 6 min read

Los design patterns tienen un problema de reputación, y se lo han ganado: generaciones de desarrolladores los aprendieron como un catecismo — 23 nombres del Gang of Four para recitar en entrevistas — y luego los aplicaron al azar, produciendo AbstractSingletonProxyFactoryBean y otras criaturas que nadie pidió. En Lasting Dynamics usamos patrones a diario y los enseñamos en nuestra academy, pero los enseñamos como lo que son: vocabulario compartido para problemas recurrentes, no puntos que coleccionar.

Esta es la versión práctica: los patrones que usamos de verdad, ejemplos en Java y — igual de importante — cuándo echar mano de uno es el error.

Qué son realmente los design patterns

Un design pattern es una solución con nombre a un problema de diseño recurrente. El valor no está en la solución (normalmente obvia una vez vista) — está en el nombre compartido. Cuando alguien dice "yo aquí haría un Strategy" en una code review, el equipo transfiere un diseño entero en tres palabras. Los patrones son compresión de comunicación antes que técnica.

El corolario honesto: un patrón aplicado donde el problema no existe no es arquitectura — es coste. La pregunta correcta nunca es "¿qué patrón puedo usar aquí?" sino "¿qué problema tengo, y tiene ya un nombre?".

Los cinco que usamos de verdad

1. Strategy — cuando el algoritmo debe ser intercambiable

El patrón más útil que existe, y el más simple: comportamientos intercambiables detrás de una interfaz.

interface PricingStrategy {
    BigDecimal price(Order order);
}

class StandardPricing implements PricingStrategy { /* ... */ }
class BlackFridayPricing implements PricingStrategy { /* ... */ }

class Checkout {
    private final PricingStrategy pricing;
    Checkout(PricingStrategy pricing) { this.pricing = pricing; }
}

Cada cadena de if (type == X) ... else if (type == Y) que crece cada sprint es un Strategy pidiendo nacer. En Java moderno, una lambda o un Function<Order, BigDecimal> suelen bastar — el patrón es la idea, no la jerarquía de clases.

2. Factory Method — cuando construir es una decisión

Si construir un objeto implica lógica (¿qué implementación? ¿qué dependencias?), esa lógica merece exactamente un hogar:

class NotifierFactory {
    Notifier forChannel(Channel c) {
        return switch (c) {
            case EMAIL -> new EmailNotifier(smtp);
            case SMS   -> new SmsNotifier(twilio);
            case PUSH  -> new PushNotifier(fcm);
        };
    }
}

El beneficio real: el código cliente depende de Notifier, nunca de las clases concretas. Es el hermano práctico de la inversión de dependencias que cubrimos en nuestra guía de clean architecture.

3. Observer — cuando algo ocurre y otros deben enterarse

Eventos de dominio: se confirma un pedido, e inventario, email y analytics deben reaccionar — sin que Order conozca a ninguno de ellos. En Java lo encontrarás como listeners, eventos de Spring o un message broker más a menudo que como implementación artesanal, pero el diseño es el mismo: el emisor no conoce a los listeners. Es el patrón que mantiene bajo el acoplamiento en los sistemas que crecen.

4. Adapter — cuando el mundo exterior no habla tu idioma

Toda integración seria tiene uno: la librería de pagos tiene su API, tu dominio tiene su interfaz, el adapter traduce. El valor estratégico es el límite: cuando el proveedor cambie su API (lo hará), reescribes el adapter, no el dominio.

5. Decorator — cuando añades responsabilidad sin tocar la clase

Logging, caché, reintentos alrededor de un servicio existente:

class CachedCatalog implements Catalog {
    private final Catalog inner;
    private final Map<String, Product> cache = new ConcurrentHashMap<>();

    public Product byId(String id) {
        return cache.computeIfAbsent(id, inner::byId);
    }
}

Misma interfaz, comportamiento enriquecido, componible libremente. (Es también el diseño detrás de medio ecosistema Java, de los streams de I/O al middleware.)

Del que hay que desconfiar: Singleton

Merece la pena cubrirlo porque las entrevistas siguen preguntando: Singleton garantiza una única instancia global. En la práctica, en 2026, es casi siempre una señal de alarma — estado global disfrazado, código difícil de testear, dependencias ocultas. Si necesitas una sola instancia, tu contenedor de inyección de dependencias te la da (Spring lo hace por defecto, con un scope singleton gestionado — algo muy distinto). Saber explicar esto en una entrevista vale más que saber implementarlo.

Cuándo un patrón es la decisión equivocada

La regla que damos en la academy: primero el problema, después el patrón — nunca al revés.

  • Si el código es más simple sin el patrón, el patrón está mal. Tres implementaciones de PricingStrategy, dos de ellas vacías, son un if disfrazado.
  • Los patrones se extraen, no se anticipan: el momento correcto para un Strategy es la segunda variante real, no la primera imaginada.
  • Si no sabes nombrar el cambio futuro del que te protege el patrón, estás haciendo ceremonia.

Una nota para la era de los agentes AI: herramientas como Claude Code generan patrones con entusiasmo — pide una factory y tendrás una preciosa, haga falta o no. El criterio sobre si hace falta sigue siendo tuyo. El mismo principio que en nuestra guía de vibe coding: la AI rellena la estructura; decidir la estructura es el trabajo.

Por qué las entrevistas siguen preguntando (y cómo responder)

Porque los patrones son un proxy rápido del vocabulario de diseño. La respuesta que funciona no es la lista de los 23 — es "aquí usaría un Strategy porque esta rama crece cada sprint, y no usaría un Singleton porque…". El porque es la señal; el nombre es solo la etiqueta.

Exactamente así los entrenamos en la Lasting Dynamics Academy: los design patterns están en el curriculum junto a arquitectura, RDBMS y testing, aplicados en tareas reales y cuestionados en la review semanal con el mentor — donde "¿qué patrón has usado y por qué?" es una pregunta real, cada semana. Gratuita, en remoto total, selectiva, con una oferta de trabajo para todo el que la completa. Si quieres que tu vocabulario de diseño se convierta en criterio, las solicitudes están abiertas.

FAQ

¿Tengo que aprenderme los 23? No. Aprende bien los cinco de arriba, más el par que tu stack use de verdad (en Java: Builder y Template Method aparecen a menudo). Al resto, reconócelos cuando los veas; nadie los usa todos.

¿Siguen siendo relevantes los design patterns con los lenguajes modernos? Sí, pero muchos se disolvieron en el lenguaje: lambdas en vez de Strategies formales, Optional en vez de Null Object, records para value objects. Los problemas que los patrones resolvían siguen existiendo; las soluciones simplemente se volvieron más ligeras. Reconocer el problema sigue siendo la habilidad.

¿Design patterns y arquitectura son lo mismo? Escalas distintas del mismo instinto: los patrones organizan clases y objetos; la arquitectura organiza módulos y límites. Un sistema puede tener patrones perfectos y una arquitectura terrible — y viceversa. Necesitas las dos cosas, y por eso la academy las enseña juntas.