Curso exprés · No. 04
La mayoría ya los reinventaste a mano. Un patrón es solo el nombre — para que un equipo pueda decir en una palabra lo que llevaría un párrafo, y reconocer la jugada antes de hacerla mal.
20 patrones · un diagrama para cada uno · hoja de referencia al final
Un patrón de diseño es una solución con nombre y reutilizable a un problema que aparece una y otra vez en el código. Es vocabulario, no una librería — no lo instalás, lo reconocés.
Design Pattern — el nombre de una jugada que ya hacés
Los futbolistas no inventan «la pared» en medio del partido. Tiene un nombre, y decir el nombre es más rápido que describir toda la jugada.
Un patrón de diseño es una jugada que los desarrolladores competentes reinventan a mano de todos modos. Ponerle nombre convierte un párrafo de explicación en una palabra que todo el equipo comparte. Cuando alguien dice «envolvelo en un Decorator», todos ven la forma al instante — y ese es todo el sentido de un patrón: un vocabulario compartido para jugadas que harías igual.
- Qué es
- Una solución con nombre a un problema que se repite en el código.
- Qué no es
- No es una librería: no se instala, se reconoce y se escribe.
- Escala
Vive dentro del código de un módulo — a diferencia de los patrones de arquitectura, que deciden el plano de todo el sistema.
- Para qué
- Lenguaje compartido: una palabra en vez de un párrafo.
Gang of Four — los patrones se descubren, no se inventan
Nadie inventó el arco. Los constructores seguían encontrando que era la forma más fuerte de salvar un vano — así que le pusieron un nombre.
La Banda de los Cuatro (Gang of Four, GoF) son los cuatro autores del libro Design Patterns. No diseñaron 23 trucos ingeniosos; catalogaron soluciones que seguían reapareciendo en el buen código. Así que un patrón no es un objetivo que cumplir — es una forma a la que llegás naturalmente cuando el problema lo pide. Si estás forzando uno, probablemente todavía no tenés el problema.
El mapa: tres familias, tres preguntas
Una cocina tiene herramientas para tres tareas: preparar la comida, emplatarla y servirla. Los patrones se dividen igual.
Los patrones de creación son sobre cómo nacen los objetos — quién los construye, y cómo. Los patrones estructurales son sobre cómo encajan los objetos en formas más grandes. Los patrones de comportamiento son sobre cómo hablan los objetos y reparten responsabilidad. Casi todo patrón clásico es una de esas tres respuestas.
Indirection — un patrón que no necesitás es solo complejidad
Una navaja suiza en el bolsillo es práctica. Atornillar las veinte herramientas a la puerta de tu casa, no.
Todo patrón agrega indirección — una capa entre vos y la cosa. Vale la pena cuando compra flexibilidad que de verdad vas a usar, y es puro coste cuando no. El error común no es ignorar los patrones; es echar mano de uno antes de que exista el problema.
Cómo leer cada patrón
Un pasaporte: todos tienen los mismos campos, así que es fácil compararlos.
Cada patrón de aquí en adelante tiene las mismas partes: su nombre en inglés (ese es el término — recordalo), una imagen de la vida cotidiana, un diagrama y una ficha con campos: problema (qué duele), idea (cómo lo resuelve), ejemplo, coste (qué pagás), cuándo usarlo y patrones relacionados. Al final hay una hoja de referencia con todos los nombres en una página.
Un patrón es un atajo para una conversación. Usalo para que te entiendan, no para parecer ingenioso.
Cómo cobran vida los objetos — sin esparcir new por todas partes ni soldar tu código a clases concretas.
Factory — pedí la cosa por su nombre, no por su receta
Una cafetera: apretás «latte» y te sale uno. No molés, no espumás, no servís vos — y no necesitás saber cómo se hace.
Una Factory te entrega un objeto sin que llames directamente a su constructor, así que el código que llama nunca depende de la clase concreta. Solo conoce la interfaz. Compra la libertad de cambiar lo que se construye sin tocar a quien lo pidió.
- Problema
new StripeProvider()está esparcido por el código — soldado a una clase.- Idea
- Pedile el objeto a una fábrica; ella decide qué clase construir.
- Ejemplo
createPaymentProvider("stripe")devuelve unPaymentProvider. Pasarse a PayPal significa cambiar la fábrica, no cada lugar de llamada.- Coste
Una capa extra. Una fábrica que construye exactamente una cosa es un mal olor.
- Cuándo usarlo
- Hay varias implementaciones, o las habrá.
- Relaciones
Abstract Factory — la misma idea para una familia entera de objetos.
Abstract Factory — toda una familia que combina, de una vez
Comprar un juego de muebles — «Victoriano» o «Moderno» — donde cada pieza llega en el mismo estilo, sin sillas desparejas.
Cuando los objetos deben venir en familias coherentes, una Abstract Factory construye el conjunto entero de una vez para que las partes encajen. Potente — pero es maquinaria pesada, y vale la pena solo cuando las familias son reales.
- Problema
- Los objetos deben combinar entre sí, y es fácil mezclarlos.
- Idea
- Una fábrica produce el conjunto entero en un solo estilo.
- Ejemplo
Un kit de UI que produce botones, menús y diálogos a juego para macOS o para Windows desde una sola fábrica.
- Coste
- Maquinaria pesada: muchas interfaces y clases.
- Cuándo usarlo
- Solo cuando las familias son reales, y hay más de una.
- Relaciones
Se construye a partir de Factory. «Una fábrica abstracta para un solo producto» es sobreingeniería clásica.
Builder — armá un objeto complejo paso a paso
Pedir una hamburguesa a medida — pan, carne, sin cebolla, queso extra — una elección a la vez, y al final «listo».
Cuando un objeto tiene muchas partes opcionales, un Builder te deja fijarlas de a una en vez de usar un constructor monstruoso con doce argumentos. Al final llamás a build() y obtenés el objeto terminado. Cambia un constructor desconcertante por una cadena legible.
- Problema
- Un constructor de doce argumentos, la mitad opcionales.
- Idea
- Fijá las partes una a una y después
build(). - Ejemplo
QueryBuilder().select("name").where("age > 18").limit(10).build().- Coste
- Una clase más al lado de la real.
- Cuándo usarlo
- El objeto tiene muchas partes opcionales.
- Relaciones
Factory decide qué construir; Builder decide cómo ensamblar algo complejo.
Singleton — exactamente uno, compartido por todos
Un país tiene un presidente. Todos los que dicen «el presidente» se refieren a la misma persona — no hay dos.
Un Singleton garantiza una única instancia con un solo punto de acceso global. Pero ojo: un singleton es estado global con abrigo bonito, y el estado global complica las pruebas y el razonamiento.
- Problema
- Necesitás exactamente una instancia compartida.
- Idea
- La propia clase garantiza una instancia y un punto de acceso.
- Ejemplo
- Un objeto de configuración o un logger del que todos leen.
- Coste
- Estado global: probar y razonar se vuelve más difícil.
- Cuándo usarlo
Rara vez. Una única instancia que pasás explícitamente suele ganarle a una a la que se llega por un global.
- Relaciones
- De creación como Factory, pero sobre «cuántos», no «cuál».
Prototype — copiá algo ya armado en lugar de construir de cero
Fotocopiar un formulario ya completado es más rápido que llenar uno en blanco desde cero.
Cuando hacer un objeto desde cero es caro o engorroso, un Prototype te deja clonar uno existente y ajustarlo. Útil cuando los objetos son costosos de construir y casi todos se parecen.
- Problema
- Construir el objeto desde cero es lento y engorroso.
- Idea
- Tomá un objeto listo, copialo, ajustá las diferencias.
- Ejemplo
Duplicar un enemigo de juego ya configurado, o un nodo de documento con estilo.
- Coste
- Copiar exige cuidado: qué se copia y qué queda compartido.
- Cuándo usarlo
Los objetos son costosos de construir y en su mayoría parecidos.
- Relaciones
- Una alternativa a Factory: no «construir», sino «copiar».
Escondé el
new. Cuantos menos lugares sepan cómo se construye un objeto, más libre sos de cambiarlo.
Cómo se componen los objetos en estructuras más grandes — encajando partes incompatibles y agregando capacidad sin reescribir.
Adapter — un convertidor de enchufe entre dos interfaces
El cargador de tu laptop en el extranjero — el aparato está bien, el enchufe está bien; solo hace falta el convertidor entre ambos.
Un Adapter envuelve una interfaz para que parezca otra, y deja que dos cosas que no fueron diseñadas para cooperar trabajen juntas. Es cómo evitás que la API de otro se filtre por todo tu código.
- Problema
La interfaz de otro no encaja con la tuya y se esparce por tu código.
- Idea
- Un envoltorio que traduce las llamadas de una interfaz a otra.
- Ejemplo
Un SDK de pagos de terceros envuelto para que cumpla tu propio
PaymentProvider.- Coste
- Una capa más que actualizar cuando cambia la API del proveedor.
- Cuándo usarlo
- Al conectar código de terceros o heredado.
- Relaciones
Envuelve un objeto como Decorator y Proxy, pero cambia la interfaz.
Decorator — agregá ingredientes sin cambiar la pizza
Una pizza simple, luego queso, luego champiñones — cada capa envuelve la anterior y agrega algo, y sigue siendo una pizza.
Un Decorator envuelve un objeto para agregar comportamiento sin modificar el original ni heredar de él. La interfaz sigue igual, así que las capas se apilan. Te deja sumar funciones en combinaciones que nadie tuvo que prever.
- Problema
Necesitás extras en cualquier combinación; una subclase para cada uno no escala.
- Idea
- Envolvé el objeto, agregá un comportamiento, mantené la interfaz.
- Ejemplo
Un flujo de datos → compresión → cifrado; cada capa se puede apilar o quitar.
- Coste
Muchos envoltorios pequeños; una pila de capas es más difícil de depurar.
- Cuándo usarlo
- Las capacidades deben combinarse en tiempo de ejecución.
- Relaciones
La misma forma que Proxy, pero el objetivo es agregar, no controlar. El caso de manual de composición sobre herencia.
Facade — una recepción simple frente a una oficina trasera desordenada
El conserje de un hotel — decís «necesito un taxi y una reserva para cenar», y él se ocupa del enredo de llamadas detrás del mostrador.
Una Facade da una entrada única y simple a un subsistema complicado, escondiendo sus piezas móviles. Reduce una superficie enorme a la única puerta que la mayoría de quienes llaman necesita.
- Problema
- Hacer algo simple exige conocer una docena de clases del subsistema.
- Idea
- Una puerta simple que orquesta el subsistema.
- Ejemplo
VideoConverter.convert(file, "mp4")orquesta en silencio códecs, búferes y flujos de audio.- Coste
La complejidad no desaparece — queda oculta. El control fino sigue yendo por fuera de la fachada.
- Cuándo usarlo
La mayoría de quienes llaman necesita uno o dos escenarios simples.
- Relaciones
Adapter cambia la interfaz de una cosa; Facade simplifica todo un subsistema.
Proxy — un sustituto que controla el acceso
El asistente de una celebridad — no llegás a la estrella directamente; el asistente filtra, agenda y a veces responde por ella.
Un Proxy se para delante de un objeto para controlar el acceso — para carga perezosa (lazy loading), permisos, caché o para hablar con algo remoto. La misma interfaz, una puerta extra al frente.
- Problema
El objeto es caro de cargar, necesita permisos o vive en otra máquina.
- Idea
- Un sustituto con la misma interfaz se pone delante del objeto real.
- Ejemplo
Un proxy de imagen que no carga el archivo real hasta que se muestra; un proxy de acceso que comprueba permisos antes de reenviar la llamada.
- Coste
- Un salto extra en cada llamada; latencia oculta para quien llama.
- Cuándo usarlo
- Carga perezosa, permisos, caché, objetos remotos.
- Relaciones
La misma forma que Decorator, otro objetivo — control de acceso.
Composite — tratá igual a un árbol y a una hoja
Una carpeta contiene archivos y otras carpetas. «Calcular el tamaño» funciona igual si se lo pedís a un archivo o a todo el árbol.
Un Composite te deja tratar de forma uniforme a un objeto individual (una hoja) y a un grupo de objetos (un compuesto) — comparten una sola interfaz. Convierte las estructuras recursivas en algo que manejás sin casos especiales en cada nivel.
- Problema
- Trabajar con un árbol exige un caso especial en cada nivel.
- Idea
- Hoja y rama comparten una interfaz; una rama solo llama a sus hijos.
- Ejemplo
Una UI donde un botón y un panel lleno de botones responden ambos a
render()ygetSize().- Coste
La interfaz común puede ser demasiado general: no toda operación tiene sentido en una hoja.
- Cuándo usarlo
- Los datos son naturalmente un árbol: carpetas, UI, documentos.
- Relaciones
Se recorre con Iterator; las operaciones nuevas se agregan con Visitor.
Composición sobre herencia: unir comportamiento en tiempo de ejecución en lugar de congelarlo en un árbol de clases.
La primera mitad de los patrones de comportamiento: cómo los objetos reparten el trabajo y se hablan — para que la responsabilidad quede bien dividida y el código correcto corra en el momento correcto.
Strategy — cambiá el algoritmo, mantené al que llama
Una app de mapas: el mismo viaje, pero elegís «más rápido», «más corto» o «evitar peajes», y traza otra ruta. Vos elegís la estrategia; la app solo la sigue.
Una Strategy vuelve intercambiable un algoritmo en tiempo de ejecución, así que quien llama sigue igual mientras el método varía. En los lenguajes modernos suele ser simplemente pasar una función en vez de toda una clase — y ese es el punto: el patrón es la idea, no la ceremonia.
- Problema
Una escalera de
ifque crece sobre variantes de un mismo algoritmo.- Idea
El algoritmo es un objeto (o función) intercambiable detrás de una interfaz.
- Ejemplo
Un checkout que recibe una
PricingStrategy: normal, de socio o de rebajas de temporada.- Coste
- Una Strategy para un algoritmo que nunca varía es peso muerto.
- Cuándo usarlo
- Dos o más variantes, elegidas en tiempo de ejecución.
- Relaciones
La misma forma que State. En el código moderno, a menudo solo una función.
Observer — suscribite y te avisan cuando cambia
Un boletín — te suscribís una vez, y cada número nuevo te llega. El editor no llama a cada lector; solo envía a la lista.
Con un Observer, los suscriptores se registran en un sujeto y reciben aviso cuando cambia — sin que el sujeto sepa quiénes son. Es la columna vertebral del código orientado a eventos y reactivo.
- Problema
Un objeto debe avisar a muchos otros de un cambio sin conocerlos por nombre.
- Idea
- Una lista de suscriptores +
notify()en cada cambio. - Ejemplo
Una celda de hoja de cálculo que refresca cada gráfico que depende de ella; los frameworks de UI reaccionando al estado; pub/sub por todas partes.
- Coste
Las cadenas de avisos son difíciles de seguir; una suscripción olvidada vive para siempre.
- Cuándo usarlo
- Varias partes independientes reaccionan a un mismo cambio.
- Relaciones
La base del código orientado a eventos — lo mismo que la arquitectura Event-driven, dentro de un solo programa.
Command — envolvé una petición como un objeto
Una comanda de restaurante — la petición «mesa 5, dos cafés» se vuelve un papelito que podés encolar, reordenar, registrar e incluso romper.
Un Command convierte una acción en un objeto independiente, para que puedas encolarla, registrarla, programarla o deshacerla. Es cómo una acción se vuelve algo que podés guardar y reproducir.
- Problema
- Una acción debe posponerse, repetirse, registrarse o deshacerse.
- Idea
- Empaquetá la acción en un objeto con todo lo necesario para ejecutarla.
- Ejemplo
Cada edición en un editor es un comando — de ahí deshacer/rehacer y las macros. Una cola de trabajos son comandos esperando su turno.
- Coste
- Un objeto por acción; hay que pensar el deshacer para cada comando.
- Cuándo usarlo
- Deshacer/rehacer, colas, macros, un registro de acciones.
- Relaciones
- A menudo va junto con Memento para deshacer.
Chain of Responsibility — pasalo hasta que alguien lo atienda
Los niveles de soporte al cliente — la recepción lo intenta, escala a un especialista, luego a un gerente, hasta que alguien puede resolverlo de verdad.
Con una Chain of Responsibility, una petición viaja por una cadena de manejadores; cada uno o la atiende o la pasa. Desacopla al que envía de quien termina haciendo el trabajo.
- Problema
El que envía no debería saber quién exactamente atenderá la petición.
- Idea
- Una cadena de manejadores: cada uno hace su parte o la pasa.
- Ejemplo
Middleware web: autenticación, luego registro, luego límite de tasa, luego la ruta misma.
- Coste
El orden de los eslabones importa; una petición puede recorrer toda la cadena sin ser atendida.
- Cuándo usarlo
Varias comprobaciones o pasos independientes antes del trabajo principal.
- Relaciones
- En la web casi siempre te lo encontrás como middleware.
Los buenos patrones de comportamiento dejan que dos piezas cooperen sin que ninguna deje a la otra cableada.
La segunda mitad de los patrones de comportamiento: cómo cambia el comportamiento de un objeto con su estado, cómo recorrés colecciones y cómo fijás un esqueleto dejando un paso abierto.
State — comportamiento que cambia con el modo en que estás
Un semáforo — verde, amarillo, rojo — donde cada color decide qué pasa ahora y qué color viene después. El mismo semáforo, otro comportamiento según el estado.
El patrón State deja que un objeto cambie su comportamiento cuando cambia su estado interno. Un enredo de if y switch se vuelve estados y transiciones claros — una pequeña máquina de estados. Convierte un lío de banderas en una máquina ordenada.
- Problema
El comportamiento depende de un modo, y el código se llena de banderas y
switch.- Idea
- Cada estado es su propio objeto con sus propias reglas y transiciones.
- Ejemplo
Un pedido que se comporta distinto como
pending,paid,shippedocancelled; cada estado conoce solo sus reglas y en qué puede convertirse.- Coste
- Muchas clases pequeñas; para dos estados basta un
ifsimple. - Cuándo usarlo
- Muchos estados, y las transiciones entre ellos importan.
- Relaciones
La misma forma que Strategy, pero el objeto cambia de estado por sí mismo mientras vive.
Iterator — recorré una colección sin ver sus entrañas
Los botones siguiente y anterior de un control remoto — pasás por los canales sin saber cómo están guardados.
Un Iterator da una forma uniforme de recorrer una colección sin exponer cómo está hecha — arreglo, árbol o lista enlazada. Este es tan útil que el lenguaje suele traerlo incorporado — for..of, generadores, __iter__. Es la señal más clara de que un patrón puede graduarse a una característica del lenguaje.
- Problema
- El código de recorrido depende de cómo está construida la colección.
- Idea
Una sola forma de obtener «el siguiente elemento», sea lo que sea que haya dentro.
- Ejemplo
for (item of collection)funciona igual sobre una lista o una estructura propia.- Coste
- Casi cero — normalmente ya viene incorporado en el lenguaje.
- Cuándo usarlo
- Siempre — pero con las herramientas incorporadas, no a mano.
- Relaciones
- Recorre los árboles construidos con Composite.
Template Method — una receta fija con un hueco para llenar
Una receta idéntica siempre — salvo «agregá la especia que prefieras» en el paso cuatro. El esqueleto es fijo; un paso es tuyo.
Un Template Method define el esqueleto de una operación en una clase base y deja que pasos específicos se sobrescriban sin cambiar la forma general. Útil cuando muchos flujos comparten forma pero difieren en un punto o dos.
- Problema
- Varios flujos de la misma forma se copian casi por completo.
- Idea
El esqueleto vive en una clase base; los pasos que varían viven en las subclases.
- Ejemplo
Un importador que abre, lee, parsea (esto lo llenás vos) y guarda; los importadores de CSV y JSON aportan solo el paso de parseo.
- Coste
- Depende de la herencia; el esqueleto es difícil de cambiar después.
- Cuándo usarlo
La forma es compartida, las diferencias están en uno o dos puntos.
- Relaciones
Strategy resuelve un problema parecido con composición en lugar de herencia.
Mediator, Visitor, Memento — el resto, en un suspiro
Una caja de herramientas tiene instrumentos que usás una vez al mes, no a diario — pero igual conviene saber que existen.
Unos pocos más se ganan su lugar de vez en cuando. Mediator — una torre de control para que los objetos hablen por un solo centro en vez de un enredo de enlaces directos. Visitor — agregar operaciones nuevas a una estructura sin editar sus clases. Memento — capturar el estado de un objeto para restaurarlo después. Conocé los nombres; echá mano de ellos solo cuando aparezca el problema exacto.
- Qué es
Un centro por el que hablan los objetos en lugar de enlazarse directamente entre sí.
- Imagen
- Una torre de control: los aviones hablan con ella, no entre sí.
- Cuándo usarlo
- Los enlaces directos entre objetos se han vuelto demasiados.
- Qué es
- Una operación nueva sobre una estructura, movida a su propio objeto.
- Ejemplo
Exportar cada figura de un documento — sin editar las clases de las figuras.
- Cuándo usarlo
La estructura es estable, pero las operaciones sobre ella no paran de multiplicarse.
- Qué es
- Un estado guardado de un objeto al que se puede volver.
- Ejemplo
Puntos de guardado en un juego, instantáneas de deshacer en un editor.
- Relaciones
- Junto con Command te da el deshacer.
Cuando un patrón se vuelve palabra clave del lenguaje, dejá de escribir el patrón y usá la palabra clave.
El catálogo es décadas de sabiduría ganada a pulso — y también un producto de su época. Usalo como un ingeniero sénior, no como una lista de verificación.
Language features — muchos patrones ya vienen incorporados
Antes dábamos indicaciones por puntos de referencia; ahora el teléfono navega. La habilidad no desapareció — fue absorbida por la herramienta.
Iterator es for..of. Strategy suele ser una función que se pasa. Decorator y Observer son ciudadanos de primera en los frameworks modernos. Cuando el lenguaje te da la forma gratis, escribir el patrón completo a mano es solo ceremonia (código repetitivo, boilerplate). La idea sigue importando; el boilerplate casi nunca.
Pattern-itis — una enfermedad real
Un cocinero que vacía todo el estante de especias en un plato no obtiene una comida más rica — obtiene una incomible.
La Pattern-itis es el clásico olor a sobreingeniería (over-engineering): echar mano de patrones para parecer sofisticado. Y ahora es peor — un asistente de IA generará con gusto una «Abstract Factory multinivel» para lo que deberían ser tres líneas. El código más simple casi siempre es la elección más sénior.
- Qué es
- Patrones por sí mismos, no para aliviar un dolor.
- Síntomas
Una fábrica abstracta para un solo producto, una Strategy para un algoritmo que nunca varía, cinco capas de indirección alrededor de un
if.- Por qué ahora es peor
Los asistentes de IA generan estas estructuras con ganas y rápido.
- Remedio
Primero el código más simple; un patrón solo cuando aparezca el dolor.
Los patrones son un vocabulario, no una ley
Conocer muchas palabras no hace a un buen escritor. Saber cuál palabra — y cuándo callar — sí.
El valor real del catálogo es el lenguaje compartido: «pongamos una Facade acá» le llega al instante a cualquiera que conozca el término, y eso vale mucho en un equipo. Pero la meta es siempre el código más simple que resuelva el problema. El patrón es un medio; nombrar uno nunca es el logro.
Aprendé todos los patrones para poder reconocerlos. Usá los menos que puedas.
Los patrones son respuestas. La habilidad es hacerlos corresponder con una pregunta real — y saber cuándo ningún patrón es la respuesta correcta.
Dejá que el patrón surja del dolor
No elegís una llave antes de encontrar el tornillo. Ves el problema, y después echás mano de la herramienta que le calza.
El buen uso de patrones suele ser un refactor, no un plano de partida: escribís lo simple, sentís un dolor concreto — esta escalera de if no deja de crecer, esta clase sabe demasiado de cómo se construye — y entonces el patrón que lo alivia resulta obvio. Forzar patrones de entrada es como se construyen catedrales que nadie pidió.
Nombralo solo cuando el nombre ayude
No decís «ejecuté una pared» en una charla casual. Pero en la cancha, con tus compañeros, la palabra ahorra una oración entera.
La ganancia de un patrón es comunicación y flexibilidad. Si nombrarlo vuelve el código más claro para la próxima persona, usá el nombre en voz alta — en el nombre de una clase, un comentario, una charla de diseño. Si la indirección no compra nada, gana el código más llano, sea o no un patrón.
Los patrones están conectados
Las palabras de un idioma no viven solas: tienen sinónimos, pares y parientes.
Adapter, Decorator y Proxy son una misma forma: un envoltorio alrededor de un objeto, con objetivos distintos. Strategy y State se parecen en la forma. Command y Memento juntos dan el deshacer. Abstract Factory está construida a partir de Factory. Composite se recorre con Iterator. Observer es la columna vertebral del código orientado a eventos.
- ¿Qué problema recurrente resuelve? Decilo en una oración.
- ¿Tengo ese problema ahora, o estoy adivinando el futuro?
- ¿Bastaría una función u objeto simple? Probá eso primero.
- ¿Mi lenguaje ya me da esto gratis?
- ¿Nombrarlo volverá el código más claro para la próxima persona — o solo más elegante?
- ¿Estoy refactorizando hacia él, o lo estoy forzando de entrada?
- Tenés una fábrica que construye exactamente una cosa.
- Una Strategy con una sola estrategia que nunca cambia.
- Más interfaces e indirección que comportamiento real.
- Agregaste el patrón para parecer sénior, no para resolver un dolor.
- Un lector nuevo necesita un diagrama UML para seguir tres líneas de lógica.
- El patrón eliminó una escalera de
if/switchque no dejaba de crecer. - Podés cambiar una implementación sin tocar a quienes llaman.
- Un compañero reconoció la forma al instante por su nombre.
- La indirección se gana su lugar — de verdad usás la flexibilidad.
- El código es más simple con el patrón que sin él, no solo más ingenioso.
Hoja de referencia: los 20 patrones y las ideas clave
Fundamentos
- Design Patternpatrón de diseño
Una solución con nombre a un problema recurrente en el código. Vocabulario, no una librería.
- Gang of FourGoF
Los autores de Design Patterns, que catalogaron 23 patrones.
- Indirectionindirección
Una capa entre vos y la cosa. El coste de todo patrón.
- Pattern-itissobreingeniería, over-engineering
Patrones de vitrina, no de dolor. El código simple casi siempre gana.
De creación
- FactoryFactory Method, fábrica
Pedí un objeto por su nombre; la fábrica elige la clase.
- Abstract Factoryfábrica abstracta
Una fábrica para toda una familia de objetos que combinan.
- Builderconstructor
Un objeto complejo paso a paso, y después
build().- Singletonúnico
Exactamente una instancia para todos. Ojo: estado global.
- Prototypeprototipo
Cloná un objeto listo y retocalo.
Estructurales
- Adapteradaptador
Un convertidor: una interfaz parece otra.
- Decoratordecorador
Un envoltorio agrega comportamiento; la interfaz sigue igual.
- Facadefachada
Una puerta simple a un subsistema complejo.
- Proxysustituto
Se para delante de un objeto y controla el acceso.
- Compositecompuesto
Una hoja y un árbol comparten una interfaz.
De comportamiento: hablar
- Strategyestrategia
Un algoritmo intercambiable; a menudo solo una función.
- Observerobservador
Los suscriptores reciben aviso de los cambios.
- Commandcomando
Una acción como objeto: encolar, registrar, deshacer.
- Chain of Responsibilitycadena de responsabilidad, middleware
Manejadores en cadena; en la web, middleware.
De comportamiento: estado y pasos
- Stateestado
Cada estado tiene sus propias reglas y transiciones.
- Iteratoriterador
Recorrer una colección sin mirar adentro. Normalmente
for..of.- Template Methodmétodo plantilla
El esqueleto es fijo; un paso es tuyo.
- Mediatormediador
Todos hablan por un solo centro.
- Visitorvisitante
Una operación nueva sin editar las clases.
- Mementoinstantánea
Guardar un estado y volver a él.
El mejor uso de un patrón de diseño es el que un lector nunca nota — porque hizo que el código pareciera obvio.