Módulo 1: Qué son de verdad los patrones
3. El verdadero superpoder: vocabulario compartido
Descripción
Al terminar esta lección vas a entender por qué el valor principal de los patrones no está en escribirlos sino en nombrarlos, y vas a tener una forma concreta de usar ese vocabulario en una conversación de equipo sin que se vuelva un problema. Vas a ver, con el mismo comentario de revisión escrito de tres maneras, cuánto comprime un nombre bien puesto. Y vas a ver el otro lado —el que casi nunca se enseña—: qué destrozos hace un nombre mal puesto, por qué nombrar mal confunde más que no nombrar, y cuál es la forma de usar el vocabulario que evita las dos trampas.
Esto importa porque hay una expectativa muy extendida y bastante equivocada sobre para qué sirve saber patrones. La expectativa es: "los aprendo para poder implementarlos". En la práctica, si llevas la cuenta de un año de trabajo, vas a descubrir que implementaste tres o cuatro y que nombraste varias docenas: en revisiones de código, en discusiones de diseño, leyendo código ajeno, explicándole a alguien nuevo cómo funciona un módulo. El vocabulario se usa todos los días; la implementación, de vez en cuando. Estudiar patrones pensando solo en la implementación es prepararse para el examen equivocado.
Y hay una razón más profunda. El vocabulario no solo transmite pensamiento: lo habilita. Cuando no tienes la palabra para algo, la pregunta sobre ese algo es difícil de formular. Un equipo que no tiene la palabra "Observer" puede sentir que su sistema de notificaciones está enredado, pero le cuesta discutirlo con precisión. El mismo equipo, con la palabra, puede preguntarse cosas concretas: "¿esto de verdad quiere ser un Observer, o estamos pagando el desacoplamiento sin necesitarlo?". Esa pregunta necesita el nombre para existir.
Conexión con el módulo: la lección 2 desarmó el patrón en tres casillas y dijo que el nombre era la mitad del valor. Esta lección cobra esa promesa: se dedica entera al nombre. La lección 4 va a explicar de dónde salieron esos nombres y por qué no se pueden inventar por decreto. La lección 5 usa el vocabulario en dirección de lectura —reconocer una estructura en código ajeno—, mientras que esta lo usa en dirección de escritura —transmitir lo que ya reconociste—. Y el módulo 7 entero es esta lección llevada a su forma profesional: el vocabulario de la revisión, incluyendo el vocabulario de lo que está mal.
Una nota de frontera antes de empezar. Aquí hablamos del vocabulario: qué palabras existen, qué comprimen y cómo se usan sin hacer daño. El oficio del review —cómo estructurar un comentario para que no genere fricción, cuándo bloquear un PR, cómo recibir una crítica— es de clean-code-and-code-review-guide. Las dos se necesitan: esa guía te enseña la conversación, esta te da las palabras.
Hablar en clave: la radio de un piloto
Escucha cinco minutos de radio aeronáutica y no vas a entender nada. Las frases son cortas, rígidas, casi sin gramática. "November-four-two-five, cleared for takeoff runway two-seven, wind two-four-zero at eight." Nadie dice por favor. Nadie improvisa sinónimos.
Eso no es descortesía ni jerga por gusto: es un vocabulario diseñado. Cada palabra tiene un significado único, acordado internacionalmente, y varias de ellas comprimen mucho. "Mayday" significa una emergencia que amenaza la vida y exige prioridad absoluta sobre todo lo demás en la frecuencia. "Pan-pan" significa una urgencia seria que todavía no amenaza la vida. Son dos palabras que separan dos situaciones que, dichas en lenguaje corriente, tomarían varias frases y quedarían ambiguas —y en las que la ambigüedad se paga carísimo—.
Tres propiedades de ese vocabulario nos interesan.
Comprime. Una palabra reemplaza un párrafo. El interlocutor no reconstruye el significado: lo recupera completo.
Es preciso porque es acordado. El valor no está en que las palabras sean bonitas, sino en que las dos personas les asignen exactamente el mismo significado. Un vocabulario compartido solo por una de las dos partes no sirve de nada.
Y cuando se usa mal, es peor que no tenerlo. Esta es la parte que menos se dice. Si alguien usa una palabra estandarizada con un significado ligeramente distinto al acordado, el otro lado no pide aclaración: entiende con total confianza algo equivocado y actúa. Esa es la falla más peligrosa de un vocabulario técnico, y por eso la aviación ha ido puliendo su fraseología durante décadas, retirando expresiones que resultaron ambiguas en incidentes reales. Podríamos considerarlo la lección más cara que ese oficio aprendió sobre el lenguaje: una frase mal escogida, dicha con confianza y entendida al pie de la letra, es más peligrosa que decir la misma idea con torpeza pero sin jerga.
Los patrones de diseño son el mismo tipo de vocabulario, con las mismas tres propiedades. Comprimen —"Adapter" reemplaza un párrafo—. Son precisos en la medida en que están acordados —y el acuerdo no es universal, ya lo veremos—. Y usados mal, mandan a tu compañero en la dirección equivocada con toda seguridad.
Ejemplo trabajado: el mismo comentario de revisión, tres versiones
Vamos al código. Estás revisando un cambio en checkout/checkout.py de Boletia. Tu compañero acaba de agregar el aviso al organizador del evento, y el bloque final de la función quedó así:
# Archivo: checkout/checkout.py
# Fragmento final de checkout(), después de cobrar con éxito.
def checkout(order):
# ... cálculo de precio, cobro con el proveedor, marcado de la orden ...
order.status = "paid"
repository.save_order(order)
# A partir de aquí: avisarle a todo el que tenga que enterarse.
customer = repository.get_customer(order.customer_id)
# 1. Al cliente, siempre por correo.
email_channel.send(customer.email, build_confirmation(order))
# 2. Al cliente por SMS, pero solo si dejó teléfono.
if customer.phone:
sms_channel.send(customer.phone, build_short_confirmation(order))
# 3. Al cliente por push, solo si tiene la app.
if customer.push_token:
push_channel.send(customer.push_token, build_push_confirmation(order))
# 4. Al organizador del evento. ← esto es lo que agregó el compañero
event = repository.get_event(order.ticket_ids[0])
organizer = repository.get_customer(event.organizer_id)
email_channel.send(organizer.email, build_organizer_alert(order, event))
# 5. A analítica, para el tablero de ventas en vivo.
analytics.track("order_paid", order_id=order.id, total=order.total)
return order
Tú ves el problema: checkout conoce por nombre a los cinco interesados. Cada vez que alguien más tenga que enterarse de una compra —el equipo de fraude, un webhook para el organizador, el sistema de facturación—, hay que volver a abrir el archivo más delicado del sistema y agregarle un bloque. La función se llama checkout, pero la mitad de su cuerpo no tiene que ver con cobrar.
Vamos a escribir ese mismo diagnóstico de tres maneras.
Versión A — sin vocabulario compartido.
"Hola. Veo que para agregar el aviso al organizador tuviste que meter cuatro líneas más al final de
checkout. Me preocupa un poco la tendencia: esta función ya le avisa a cinco destinatarios distintos y los conoce a todos por su nombre. Cada vez que aparezca alguien nuevo que necesite enterarse de una compra —creo que fraude va a pedirlo el mes que viene— vamos a tener que volver a abrir este archivo, que es el que menos ganas tenemos de tocar. Además, si alguno de estos envíos falla, se cae el checkout completo aunque el cobro ya haya salido bien. ¿No convendría quecheckoutsolo anuncie que la orden se pagó, y que los interesados se suscriban a ese anuncio por su cuenta? Así agregar a fraude sería registrar un suscriptor nuevo sin tocar esta función."
Es un buen comentario. Es claro, correcto, completo. Te tomó unos seis minutos escribirlo y tu compañero necesita leerlo dos veces para reconstruir la estructura que propones, porque se la diste en prosa.
Versión B — con vocabulario compartido.
"Esto está pidiendo un Observer: que
checkoutpubliqueorder_paidy que los cinco destinatarios se suscriban. Así fraude entra el mes que viene sin tocar esta función, y un canal caído deja de tumbar el cobro. El costo es que el flujo deja de leerse de corrido —tendrías que ir a la lista de suscriptores para saber quién se entera—. Con cinco interesados y más en camino, creo que sale a cuenta."
Cuarenta segundos. Tu compañero, que conoce la palabra, ya vio la estructura completa: el publicador, el evento, la lista de suscriptores, el desacoplamiento. Y —esto es clave— también recibió el costo, porque lo dijiste.
Versión C — con vocabulario mal usado.
"Esto está pidiendo una Factory para los canales de notificación."
Diez segundos, y un daño real. Factory es otra cosa: resuelve cómo se construye un objeto, no quién se entera de un evento. Tu compañero, que confía en ti y conoce la palabra, se va a pasar la tarde escribiendo una fábrica de canales de notificación —NotificationChannelFactory.create("sms")— que no resuelve absolutamente ninguno de los dos problemas que detectaste: checkout seguiría conociendo a los cinco destinatarios, y un canal caído seguiría tumbando el cobro. Peor: ahora hay una abstracción nueva en el sistema, con su costo, que nadie pidió y que a nadie le sirve. Y cuando alguien pregunte por qué está ahí, la respuesta va a ser "lo pidió la revisión".
Qué esperar de esta comparación. Cuatro cosas, y la última es la que más me interesa.
Primero, el diagnóstico fue idéntico en A y en B. El vocabulario no te hizo ver más. Te hizo transmitir más barato: de seis minutos a cuarenta segundos, con menos pérdida en el camino. En un equipo que hace veinte revisiones por semana, esa diferencia es la que decide si las observaciones de diseño se dicen o se dejan pasar por pereza.
Segundo, fíjate en que la versión B también dijo el costo. Esa es la forma correcta de usar el vocabulario y volveremos sobre ella en un momento: el nombre no reemplaza al argumento, lo abrevia. Un comentario que solo dice "esto pide un Observer" está a medio camino.
Tercero, la versión C hizo más daño que no comentar nada. Si tú no hubieras dicho nada, el código habría quedado como estaba: imperfecto pero honesto. Con el comentario equivocado, el código va a quedar imperfecto y con una abstracción de más. Nombrar mal no es un error neutro: tiene costo negativo. Por eso la regla práctica es: si no estás seguro del nombre, describe la estructura en prosa. La versión A es siempre mejor que la versión C.
Y cuarto, algo sobre la asimetría de la confianza. La versión C funciona —hace daño— precisamente porque tu compañero confía en el vocabulario. Si le hubieras dicho una frase vaga, habría preguntado. El nombre técnico cierra la conversación: activa el significado completo y elimina la duda. Esa es su virtud y su peligro, exactamente como en la radio del piloto.
Qué le pasa a un equipo cuando comparte vocabulario
Los efectos son cuatro, y van de lo obvio a lo interesante.
1. Compresión. El más visible y el menos profundo. Una palabra en lugar de un párrafo. Ya lo viste. Vale la pena notar que la compresión no es solo ahorro de tiempo: es ahorro de atención, que es el recurso escaso de verdad. Un comentario de revisión de seis líneas se lee a medias; uno de dos, completo.
2. Precisión. Cuando dices "Adapter", no dices "una clase que envuelve a otra" —eso también describe a un Decorator, a un Proxy y a un Facade—. Dices específicamente: una clase que envuelve a otra para traducir su interfaz a la que tu código espera. El nombre carga esa distinción. Un equipo sin vocabulario tendría que decirla explícita cada vez, y casi siempre no la dice, y ahí empieza el malentendido.
3. Memoria colectiva. Esta ya no se nota en una conversación sino en una base de código. Cuando un equipo comparte vocabulario, ese vocabulario termina en los nombres de las clases, en los comentarios y en la documentación. Alguien que entra al equipo dos años después abre payments/provider.py, ve que hay una forma común y tres implementaciones, y entiende la intención en diez segundos —no porque alguien se la haya explicado, sino porque la estructura es reconocible—. El vocabulario compartido convierte el código en algo legible por extraños. Ese es, en el fondo, el motivo por el que los patrones importan en un proyecto que dura años.
4. Habilita preguntas que antes no se podían hacer. Este es el efecto más interesante y el que casi nadie menciona. Sin la palabra, un equipo puede sentir que algo está mal pero no puede discutirlo con filo. Con la palabra, aparecen preguntas nuevas:
- "¿Esto de verdad quiere ser un Observer, o metimos un evento donde bastaba una llamada?"
- "Tenemos tres Adapters y ninguno adapta nada: las tres APIs ya tenían la misma forma. ¿Los quitamos?"
- "Aquí hay un Singleton disfrazado y por eso los tests se pisan entre sí."
Ninguna de esas tres frases se puede pensar cómodamente sin el nombre. Y fíjate que dos de las tres son preguntas para quitar estructura, no para agregarla. Eso es lo que quería mostrarte: el vocabulario no empuja a poner patrones. Un vocabulario bien instalado permite auditar los que ya están, que es la mitad del criterio que promete esta guía.
Hay un quinto efecto, más discreto, que conviene mencionar. En una entrevista de trabajo o en una discusión con alguien de más experiencia, el vocabulario funciona como señal de que entiendes el terreno. No porque impresione —quien intenta impresionar con nombres se nota a un kilómetro—, sino porque permite que la conversación arranque en un nivel más alto. Es la diferencia entre pasar diez minutos explicando qué estructura tenía el código que refactorizaste y decirlo en una frase para dedicar los diez minutos a por qué lo hiciste. Lo segundo es una conversación mucho mejor.
El lado oscuro: cuando el nombre estorba
Ya viste la falla más obvia —el nombre incorrecto—. Hay dos más, y las tres se combinan en las peores discusiones de diseño que te van a tocar.
Falla 1: el nombre incorrecto. Decir "Factory" cuando es "Builder", "Adapter" cuando es "Facade", "Observer" cuando es "Command". Ocurre más de lo que se admite, sobre todo con las parejas parecidas —Adapter y Facade se confunden todo el tiempo, y Strategy y Template Method también—. La consecuencia ya la viste: el otro lado actúa con confianza sobre información equivocada.
Cómo protegerte: si no estás seguro, describe la estructura. "Una clase por proveedor, todas con el mismo método, y el checkout recibiendo la que toca" es tan útil como el nombre y no puede estar equivocada. Y si alguien te da un nombre y no calza con lo que ves, la pregunta correcta no es "¿estás seguro?" sino "¿me lo describes sin el nombre?". Casi siempre, al describirlo, el otro se da cuenta solo.
Falla 2: el nombre como sentencia. Es la falla social, no la técnica. Alguien escribe en una revisión: "esto es un God object", y ahí termina el comentario. El nombre es correcto. El efecto es una persona a la defensiva y una conversación que no avanza, porque un nombre solo, sin problema y sin propuesta, se lee como un juicio sobre quien escribió el código.
Compara:
- "Esto es un God object." → suena a veredicto.
- "Esta clase se está volviendo un God object: ya toca pagos, notificaciones y reportes, y cualquier cambio en cualquiera de los tres la obliga a moverse. ¿Sacamos la parte de reportes a su propio módulo como primer paso?" → suena a diagnóstico compartido y ofrece un camino.
El nombre no cambió. Cambió que vino acompañado de por qué y de qué sigue. El módulo 7 le dedica una lección entera a esto ("el patrón como conversación, no como sentencia"), porque es la diferencia entre un equipo donde el vocabulario ayuda y uno donde el vocabulario es un arma.
Falla 3: el nombre como sustituto del argumento. La más sutil y la más frecuente entre gente con experiencia media. Alguien propone una estructura y la justifica diciendo su nombre, como si el nombre fuera la razón.
— ¿Por qué metiste una Factory aquí? — Porque es el patrón Factory.
Eso no es un argumento; es una etiqueta. El argumento sería: "porque hoy hay tres proveedores, el mes que viene entra el cuarto, y la decisión de cuál usar está hoy repetida en cuatro lugares del código; con la fábrica queda en uno solo". Ese sí se puede discutir, verificar y —si estás equivocado— refutar.
La forma general de la falla es peligrosa porque el nombre otorga autoridad prestada. Suena a que hay un libro detrás que ya decidió. Y la respuesta a eso es la casilla 3 de la lección anterior: ningún libro puede decidir por ti, porque las consecuencias dependen de tu contexto —cuántas variantes tienes, cuánto cambia esto, quién mantiene el código—.
La prueba de bolsillo, para ti y para los demás: si quitas el nombre del patrón de tu justificación, ¿queda un argumento en pie? Si al quitarlo no queda nada, no tenías un argumento: tenías una etiqueta.
La forma sana de usar el vocabulario
De todo lo anterior sale una fórmula simple, que puedes usar tal cual en revisiones y discusiones. Tres piezas, en este orden:
[el problema concreto] + [el nombre] + [el tradeoff]
- El problema concreto primero, en lenguaje de dolor: "cada vez que alguien más necesita enterarse de una compra, hay que abrir
checkout.py". Esto ancla la conversación en algo verificable y evita que suene a preferencia estética. - El nombre después, como abreviatura de la estructura que propones: "esto pide un Observer". Ahora el nombre no es la razón: es el atajo para describir la solución.
- El tradeoff al final, dicho por ti antes de que te lo pregunten: "a cambio, el flujo deja de leerse de corrido". Decir el costo tú mismo hace dos cosas: demuestra que lo pensaste y le da al otro un lugar por donde discutir sin tener que atacarte.
Compara la fórmula completa con sus versiones truncadas:
| Versión | Cómo se lee |
|---|---|
| Solo el nombre | Etiqueta. Suena a sentencia o a autoridad prestada |
| Problema + nombre | Buen comentario. Le falta la mitad de la información para decidir |
| Nombre + tradeoff | Sospechoso: propone una solución sin haber mostrado el problema |
| Problema + nombre + tradeoff | Una propuesta de ingeniería que el equipo puede evaluar |
Y una cuarta pieza opcional, que en la práctica vale mucho: el tamaño del paso. "Podríamos empezar solo con el organizador y fraude, y dejar analítica como está." Una propuesta que cabe en un cambio pequeño se acepta mucho más seguido que una que exige reescribir un módulo. El módulo 8 se ocupa de esto en serio.
Una última advertencia, que va contra la corriente de casi todo el material sobre patrones. No hace falta que uses el nombre. Si estás en un equipo donde el vocabulario no está instalado —y hay muchos, perfectamente buenos—, insistir en los nombres genera distancia en vez de comunicación. En ese contexto la versión A del ejemplo, la de prosa, es la correcta. El objetivo nunca fue usar la palabra: era transmitir la estructura. Cuando la palabra ayuda, se usa; cuando no, se describe. Quien usa el vocabulario para marcar nivel y no para comunicar ha entendido esta lección al revés.
Errores comunes
Estudiar patrones pensando solo en implementarlos (de estudio). Qué pasa: alguien aprende un patrón escribiendo una versión de juguete, se siente listo, y en el trabajo descubre que casi nunca le toca implementar uno desde cero —pero sí le toca todos los días leer código ajeno, comentar revisiones y explicar módulos—. Para eso no se preparó. Por qué pasa: implementar es lo que se puede practicar en un ejercicio cerrado, y por eso todos los cursos lo evalúan. Nombrar requiere código real y ajeno. Cómo detectarlo: si puedes escribir un Decorator pero al abrir un archivo desconocido no reconoces uno, tienes la mitad que menos se usa. Cómo corregirlo: practica en dirección de lectura. Abre cualquier proyecto de código abierto que uses y trata de nombrar tres estructuras. La lección 5 te da la técnica y la lección 8 lo convierte en el proyecto del módulo.
Usar el nombre como si fuera el argumento (de criterio). Qué pasa: alguien justifica una decisión de diseño diciendo el nombre del patrón, y cuando le preguntan por qué, repite el nombre con otras palabras. La discusión se estanca porque no hay nada que discutir: no se puso ningún hecho sobre la mesa. Por qué pasa: el nombre trae autoridad prestada —suena a que un libro ya decidió— y esa sensación es cómoda. Además, formular el argumento real exige haber pensado la casilla 3, y eso cuesta. Cómo detectarlo: quita el nombre del patrón de tu frase y mira si queda algo en pie. Cómo corregirlo: usa la fórmula problema + nombre + tradeoff, siempre en ese orden, y acostúmbrate a decir el costo tú mismo antes de que te lo pregunten.
Nombrar mal por parecerse (técnico). Qué pasa: alguien confunde dos patrones vecinos —Adapter con Facade, Strategy con Template Method, Factory con Builder— y manda al equipo en una dirección que no resuelve el problema detectado. El daño es mayor que no haber comentado, porque el otro lado actúa con confianza. Por qué pasa: las parejas vecinas se ven casi iguales en el diagrama y solo se distinguen por la intención, que es justo lo que un diagrama no muestra. Adapter y Facade son los dos "una clase que envuelve a otra"; lo que los separa es que uno traduce a una interfaz que ya existía y el otro simplifica una superficie complicada. Cómo detectarlo: si tu justificación del nombre describe la forma y no la intención, hay riesgo de confusión. Cómo corregirlo: cuando dudes, describe la estructura en prosa. Es más largo y no puede estar mal. Y cuando quieras verificar un nombre, no compares el diagrama: compara el problema que cada patrón dice resolver.
Ejercicios
Ejercicio 1 — Traduce prosa a vocabulario, y verifica. Aquí hay tres comentarios de revisión escritos sin vocabulario. Para cada uno: (a) propón el nombre del patrón que comprime esa descripción, si es que hay uno; (b) reescribe el comentario usando la fórmula problema + nombre + tradeoff; (c) si no estás seguro del nombre, dilo y explica por qué es la respuesta correcta.
- "Cada uno de estos tres exportadores hace exactamente los mismos cuatro pasos en el mismo orden y solo cambia el tercero. Si mañana cambiamos el orden, hay que acordarse de tocar los tres."
- "Esta clase envuelve la librería del proveedor de pago y le cambia los nombres de los métodos para que se parezcan a lo que el resto de nuestro código ya usaba."
- "Tenemos una clase base abstracta con cinco métodos, un registro que descubre implementaciones por nombre de módulo, y exactamente una implementación desde hace dos años."
Ver solución
1. El nombre es Template Method: un esqueleto fijo definido en un solo lugar, con uno o más pasos que cada variante rellena. Comentario con la fórmula: "Los tres exportadores repiten el mismo esqueleto de cuatro pasos y solo cambia el formato; si mañana movemos el orden hay que acordarse de los tres. Esto pide un Template Method: el esqueleto una vez, y cada formato aportando solo su paso. El costo es que leer una exportación completa deja de ser leer un archivo, y que los tres quedan atados a un esqueleto común —si alguno diverge después, va a incomodar."
2. El nombre es Adapter: traduce la interfaz de algo externo a la que tu código espera. Ojo con la confusión más común aquí, que es llamarlo Facade. La diferencia es la intención: Facade simplifica una superficie complicada hacia una interfaz nueva que tú inventas; Adapter traduce hacia una interfaz que ya existía en tu código. En el enunciado la pista es literal: "para que se parezcan a lo que el resto de nuestro código ya usaba". Eso es adaptar.
3. Aquí la respuesta correcta incluye decir que no es un patrón, es un anti-patrón. Lo que se describe es un mecanismo de extensión completo para algo que nunca tuvo más de una implementación —el rincón plugins/ de Boletia—. El nombre que existe para esto es "abstracción especulativa" o, más coloquialmente, sobre-diseño; el módulo 2 le dedica una lección con el nombre completo. Comentario con la fórmula: "Tenemos registro dinámico, clase base abstracta y una sola implementación desde hace dos años: entender el mapa de asientos cuesta tres archivos en vez de uno. Propongo quitar el andamio y dejar la implementación directa. El costo es que si algún día llega una segunda implementación habrá que reintroducir la indirección —pero eso será con el problema real enfrente, no imaginado."
Por qué funciona: los tres casos cubren las tres situaciones que te vas a encontrar. En el primero el nombre está claro. En el segundo hay una pareja vecina que se confunde constantemente y solo se distingue por la intención. Y en el tercero la respuesta correcta es que sobra estructura, que es la mitad del criterio de esta guía.
Ejercicio 2 — Detecta el nombre usado como argumento. Para cada frase, decide si contiene un argumento o solo una etiqueta. Si es una etiqueta, reescríbela como argumento inventando los datos que harían falta.
- "Metí una Factory porque programar contra interfaces es una buena práctica."
- "Le puse un Singleton a la conexión de base de datos porque es el patrón estándar para eso."
- "Saqué las reglas de precio a clases separadas porque marketing pidió dos tipos de boleto nuevos este trimestre y cada tipo nos obligaba a tocar el calculador y otras dos funciones que preguntan por
kind."
Ver solución
1. Etiqueta. "Buena práctica" no es un argumento: es una apelación a autoridad sin contexto. Además, "programar contra interfaces" es un principio, no una razón para introducir una fábrica; las dos cosas ni siquiera son el mismo tema. Como argumento sería: "metí una Factory porque la decisión de qué proveedor construir estaba repetida en cuatro lugares —el checkout, el reintento, el reembolso y el script de conciliación— y cada vez que agregamos uno había que acordarse de los cuatro. Ahora la decisión vive en un lugar. A cambio, para saber qué objeto llega al checkout hay que abrir la fábrica."
2. Etiqueta, y una de las peligrosas. "Es el patrón estándar para eso" es exactamente autoridad prestada. Además, el Singleton es el patrón del que más hay que desconfiar —el módulo 4 le dedica una lección— porque introduce estado global y suele romper los tests, que empiezan a pisarse entre sí. Como argumento honesto sería: "usé una instancia única porque abrir una conexión por petición nos estaba agotando el pool bajo carga; a cambio, tuve que agregar una forma de reemplazarla en los tests, porque si no comparten estado." Fíjate que el argumento honesto incluye el costo y cómo lo mitigaste, y eso es lo que lo vuelve discutible.
3. Argumento. Tiene un hecho verificable (dos tipos nuevos este trimestre), un dolor concreto y contado (tres lugares que tocar por cada tipo) y no depende del nombre: si quitas "clases separadas" de la frase, el argumento sigue en pie. Se le podría pedir el tradeoff explícito —"a cambio pasamos de un archivo a seis"— para que quede completo, pero ya es una propuesta de ingeniería.
Por qué funciona: la prueba de quitar el nombre y ver si queda algo es rápida y funciona en las dos direcciones —para auditar los argumentos de otros y, más útil, para auditar los tuyos antes de mandarlos—.
Ejercicio 3 — Escribe el comentario de revisión completo. Vuelve al fragmento de checkout() que abrió esta lección. Imagina que tu equipo no comparte el vocabulario de patrones: son buenos programadores pero nadie usa esos nombres. Escribe el comentario de revisión que dejarías, sin usar ni una sola vez el nombre de un patrón, respetando de todos modos la fórmula problema + solución + tradeoff. Después responde: ¿qué perdiste al no usar el nombre y qué ganaste?
Ver solución
Un comentario posible:
"El aviso al organizador quedó bien. Una observación sobre la tendencia, no sobre tu cambio:
checkoutya conoce por nombre a cinco destinatarios y la mitad de su cuerpo no tiene que ver con cobrar. Cada vez que alguien más necesite enterarse de una compra —fraude va a pedirlo pronto— vamos a tener que volver a abrir este archivo, que es el que menos ganas tenemos de tocar. Y hoy, si un envío falla, se cae el checkout completo aunque el cobro ya haya salido bien.Una alternativa: que
checkouttermine anunciando 'la orden 123 se pagó' y que cada interesado se registre por su cuenta para escuchar ese anuncio. Agregar a fraude sería registrar un escucha nuevo en su propio archivo, sin tocar este. Y un escucha que falle no arrastraría al cobro.El costo es real y quiero dejarlo dicho: hoy lees
checkoutde arriba a abajo y sabes exactamente quién se entera. Con el anuncio, esa pregunta se contesta en otro lado, en la lista de escuchas. Si mañana algo no llega, la depuración es más larga. Con cinco interesados y más en camino me parece que sale a cuenta, pero si prefieres esperar a que fraude lo pida de verdad, también me parece razonable —podríamos empezar solo con organizador y fraude y dejar los demás como están."
Qué perdiste: brevedad, sobre todo. El comentario pasó de cuarenta segundos a tres o cuatro minutos de escritura y de lectura. También perdiste algo de precisión: describiste la idea general del anuncio y los escuchas, pero no transmitiste automáticamente los detalles que el nombre "Observer" carga —la forma exacta de suscribirse, qué pasa con el orden de los escuchas, si es síncrono o asíncrono—. Esas cosas quedarán para la conversación siguiente.
Qué ganaste: que se entienda. En un equipo sin el vocabulario instalado, la palabra "Observer" habría producido una de dos reacciones: alguien que asiente sin entender, o alguien que siente que le están hablando por encima. Ninguna de las dos ayuda a que el código mejore. Además, ganaste algo que el nombre a veces esconde: al describirlo en prosa, tú mismo tuviste que verificar que la estructura resolvía los dos problemas que detectaste. El nombre permite saltarse esa verificación, y de ahí salen la mitad de los nombres mal usados.
Por qué funciona: el objetivo nunca fue usar la palabra. Era transmitir la estructura y su costo. La palabra es un atajo cuando el otro la tiene, y un obstáculo cuando no. Reconocer cuál de los dos casos tienes enfrente es parte del criterio.
Resumen y siguiente paso
En esta lección viste que el valor principal de los patrones no está en escribirlos sino en nombrarlos, y por qué: en un año de trabajo vas a implementar unos pocos y vas a nombrar decenas. Usamos la fraseología de la radio aeronáutica para ver las tres propiedades de un vocabulario técnico —comprime, es preciso porque está acordado, y usado mal es peor que no tenerlo—. Escribimos el mismo comentario de revisión sobre checkout() de Boletia de tres maneras y viste que el diagnóstico era idéntico: lo que cambió fue el costo de transmitirlo, de seis minutos a cuarenta segundos, y que la versión con el nombre equivocado hizo más daño que no comentar.
Viste los cuatro efectos del vocabulario compartido en un equipo —compresión, precisión, memoria colectiva en el propio código, y la habilitación de preguntas que antes no se podían formular, varias de ellas para quitar estructura—. Y viste las tres fallas del lado oscuro: el nombre incorrecto, el nombre como sentencia y el nombre como sustituto del argumento, con su prueba de bolsillo —quítalo de tu frase y mira si queda algo en pie—. Te queda la fórmula sana: problema concreto + nombre + tradeoff, y el permiso explícito de no usar el nombre cuando el equipo no lo comparte.
Antes de avanzar deberías poder: explicar por qué nombrar vale más que implementar; escribir un comentario de revisión con la fórmula de tres piezas; y detectar cuándo alguien —incluido tú— está usando una etiqueta en lugar de un argumento.
Queda una pregunta abierta que hemos estado esquivando. Si los nombres son tan útiles, ¿de dónde salieron? ¿Quién decidió que se llamara "Observer"? Y sobre todo: ¿por qué no puedo inventar un patrón nuevo esta tarde y ponerle nombre? La lección 4 cuenta ese origen —que empieza, curiosamente, en la arquitectura de edificios— y explica por qué los patrones se descubrieron en lugar de diseñarse. Esa distinción, que parece histórica y anecdótica, tiene una consecuencia muy práctica: explica por qué un patrón aplicado sin tener el problema es una solución sin problema.
Recursos
- Refactoring Guru — catálogo de patrones — útil aquí como diccionario de consulta rápida cuando dudes de un nombre. Compara siempre la sección de intención, no el diagrama.
- Adapter vs Facade vs Decorator vs Proxy (Martin Fowler, "GoF patterns compared") — el bliki de Fowler tiene varias entradas cortas que aclaran justamente las parejas que más se confunden.
- Ubiquitous Language (Martin Fowler) — la idea, que viene del diseño guiado por el dominio, de que un equipo y su código deben compartir un mismo vocabulario. Es esta lección aplicada al lenguaje del negocio en vez del de la estructura.
- How to Do Code Reviews Like a Human (Michael Lynch) — sobre el lado social del comentario de revisión: cómo se dice algo cierto sin que suene a sentencia. Complemento directo de la falla 2.