El catàleg ja és complet: 23 patrons, tres famílies, i PideYa sencera com a demostració. Però els problemes reals no arriben etiquetats — cap tiquet de Jira no diu "aplicar Strategy aquí". Arriben com a símptomes: un switch que creix, una classe que ningú no vol tocar, un requisit que obliga a canviar cinc fitxers. Aquesta lliçó ensenya el mètode per anar del símptoma al patró (o a cap patró, que també és una elecció): anomenar el problema abans que la solució, analitzar-ne les forces, fer les preguntes de diagnòstic correctes i validar la resposta abans d'escriure una sola línia. És la primera lliçó de l'ofici: la diferència entre tenir les eines i ser bon fuster.

Contingut

  1. Primer el problema, després el patró
  2. El catàleg de forces: què varia i què ha de romandre estable
  3. Preguntes de diagnòstic per família
  4. L'arbre de decisió global del catàleg GoF
  5. Tres casos de PideYa resolts amb el mètode
  6. "Espera fins que faci mal": el patró que no es tria per endavant
  7. Exercicis i conclusió

Primer el problema, després el patró

L'error més comú en aplicar patrons no és triar malament entre Strategy i State: és començar pel patró. Qui pregunta "on puc encabir un Visitor?" ja ha perdut — té una solució buscant problema. El mètode correcte inverteix l'ordre:

  1. Descriu el problema sense anomenar cap patró. En una o dues frases, en llenguatge de negoci i de codi: "cada cop que màrqueting afegeix un tipus de cupó, toquem la classe de checkout i se'ns escapa algun cas".
  2. Identifica les forces. Què canvia sovint? Què ha de quedar intacte? Qui no ha de conèixer qui? (apartat següent).
  3. Classifica el problema per família: va de crear objectes, de compondre estructures o de coordinar conducta?
  4. Aplica les preguntes de diagnòstic d'aquesta família i arriba a un o dos candidats.
  5. Valida contra la intenció i l'acarament. Llegeix la secció "aplicabilitat" del candidat i el seu acarament amb el patró veí (les comparatives existeixen per a això). Si la intenció del patró no coincideix amb la teva frase del pas 1, torna a començar.
  6. Passa els cinc filtres de la balança: problema anomenable, eix de canvi real, dolor present, equip preparat, benefici més gran que el cost.

Fixa-t'hi: el patró apareix al pas 4, no a l'1. Tot el que ve abans és anàlisi del problema — i és la part que distingeix el professional.

El catàleg de forces: què varia i què ha de romandre estable

Els GoF ho van escriure al pròleg i és la frase més útil del llibre: "encapsula allò que varia". Cada patró protegeix una zona estable d'una zona variable concreta. Identificar l'eix de variació del teu problema és identificar mitja resposta:

Allò que varia (o que vols poder variar) Allò que ha de romandre estable Família / candidats
La classe concreta que s'instancia El codi que la usa Factory Method, Abstract Factory
Com es construeix un objecte complex La seva representacio final i les invariants Builder
El punt de partida d'un objecte nou El procés que el consumeix Prototype
La interfície que ofereix un tercer La interfície que el teu codi espera Adapter
Dues dimensions independents alhora Que no explotin combinades en subclasses Bridge
Quantes responsabilitats extres porta un objecte La seva interfície i el seu nucli Decorator
L'estructura interna (fulla o grup) El tractament uniforme des de fora Composite
Els passos interns d'un procés multiclasse La crida única del client Facade
L'algorisme amb què es fa una cosa El context que l'invoca Strategy
Allò permès segons l'etapa de vida Les operacions que el client invoca State
Qui reacciona a un canvi L'objecte que canvia Observer
Qui atén una petició L'emissor de la petició Chain of Responsibility
Les operacions sobre una estructura Les classes de l'estructura Visitor
Passos concrets d'un flux L'esquelet del flux Template Method

La taula no substitueix les lliçons: és l'índex invers. La teva feina davant d'un problema real és omplir la primera columna amb honestedat — i si no pots ("tot pot canviar" no és una resposta), és que encara no entens el problema prou bé per posar-hi un patró.

Dues preguntes complementàries afinen les forces:

  • La variació és de dades o de comportament? Si les variants només difereixen en valors (tarifa 2,99 vs. 4,99), n'hi ha prou amb configuració o un enum; els patrons paguen quan difereix el codi.
  • Qui decideix la variant i quan? El programador en compilar (l'herència pot bastar), la configuració en arrencar (fàbriques, injecció), o l'usuari/estat en calent (Strategy, State)?

Preguntes de diagnòstic per família

Abans de baixar a patrons concrets, classifica el problema. Tres preguntes de triatge:

  • El dolor apareix en escriure new? — qui crea, quina variant, amb quants arguments, amb quin cost → família creacional.
  • El dolor apareix en dibuixar el diagrama de classes? — interfícies que no encaixen, jerarquies que exploten, subsistemes tentaculars, objectes caríssims → família estructural.
  • El dolor apareix en seguir el flux en execució? — qui crida qui, qui s'assabenta de què, on viu un algorisme, què es pot desfer → família de comportament.

I dins de cada família, les preguntes que ja coneixes de les comparatives — aquí condensades:

Família Pregunta de diagnòstic Si la resposta és sí...
Creacional El client sap què vol però no quina classe concreta? Factory Method / Abstract Factory
Creacional La construcció té molts opcionals o passos amb ordre? Builder
Creacional Crear des de zero és car o el punt de partida és "un com aquell"? Prototype
Creacional De debò només n'ha d'existir un... i no n'hi ha prou amb injectar-lo? Singleton (amb la crítica de 02-02)
Estructural Existeix codi correcte amb la interfície equivocada? Adapter
Estructural Hi ha part-tot amb tractament uniforme? Composite
Estructural Cal sumar responsabilitats sense tocar la classe ni subclassificar? Decorator / Proxy (segons qui controli: acarament a 03-09)
Comportament Molts s'han d'assabentar que un ha canviat, sense acoblar-s'hi? Observer
Comportament Allò permès depèn de l'etapa, amb transicions? State
Comportament Hi ha algorismes alternatius triats des de fora? Strategy
Comportament Les peticions s'han d'encuar, auditar o desfer? Command

L'arbre de decisió global

Les comparatives de cada mòdul (creacionals, estructurals, comportament) contenen els arbres fins per família. Aquest és el nivell superior que et deixa a la porta de l'arbre correcte:

flowchart TD
    A[Problema de disseny<br/>anomenat sense citar patrons] --> B{On fa mal?}
    B -- "En crear objectes:<br/>qui, quin, com, quants" --> C[Familia CREACIONAL]
    B -- "En l'estructura:<br/>interficies, jerarquies,<br/>composicio, cost" --> D[Familia ESTRUCTURAL]
    B -- "En la conducta:<br/>flux, avisos, algorismes,<br/>estat, historial" --> E[Familia COMPORTAMENT]

    C --> C1{Varia la classe, la<br/>construccio o l'origen?}
    C1 -- Classe concreta --> C2[Factory Method /<br/>Abstract Factory]
    C1 -- Construccio complexa --> C3[Builder]
    C1 -- Copiar un existent --> C4[Prototype]
    C1 -- Instancia unica --> C5[Singleton... o injeccio]
    C -.-> CREF[Arbre fi: llico 02-07]

    D --> D1{Adaptar, compondre,<br/>embolcallar o simplificar?}
    D1 -- Interficie incompatible --> D2[Adapter]
    D1 -- "Part-tot / 2 dimensions" --> D3[Composite / Bridge]
    D1 -- Embolcallar amb alguna cosa mes --> D4[Decorator / Proxy]
    D1 -- Subsistema complex --> D5[Facade / Flyweight]
    D -.-> DREF[Arbre fi: llico 03-09]

    E --> E1{Avisar, encapsular peticio,<br/>variar conducta o operar<br/>sobre estructures?}
    E1 -- Avisar / coordinar --> E2[Observer / Mediator]
    E1 -- Peticio com a objecte --> E3[Command / Chain / Interpreter]
    E1 -- Variar comportament --> E4[Strategy / State /<br/>Template Method]
    E1 -- Estructures i estat --> E5[Iterator / Visitor / Memento]
    E -.-> EREF[Arbre fi: llico 04-13]

Usa'l com s'usa una brúixola: t'orienta, no et porta fins a la porta. La confirmació final sempre és contra la intenció del patró i el seu acarament amb el veí confusible.

Tres casos de PideYa resolts amb el mètode

Cas creacional: els contractes de restaurant

El tiquet: "En donar d'alta un restaurant cal generar-ne el contracte. Avui n'hi ha dos tipus (comissió estàndard i tarifa plana premium) i legal n'anuncia un tercer (marketplace pur) per al trimestre vinent. L'alta avui fa new ContracteComissio(...) o new ContractePla(...) segons un if sobre un string."

  1. Problema sense patró: "el procés d'alta ha de generar el contracte correcte sense conèixer les classes concretes de contracte, perquè els tipus creixen".
  2. Forces: varia la classe concreta instanciada; ha de romandre estable el flux d'alta (validar → crear contracte → signar → activar). La variació és de comportament (cada contracte calcula liquidacions de manera diferent), no només de dades.
  3. Família: el dolor és al new → creacional.
  4. Diagnòstic: el client sap què vol ("un contracte per a aquest restaurant") però no quina classe? Sí. Famílies completes de productes coordinats per mercat? No, és un producte solt. → Factory Method (o la seva variant amb registre de Suppliers, com el RegistreNotificadors de 02-03).
  5. Validació: intenció de Factory Method — "definir una interfície per crear un objecte, deixant que les subclasses decideixin quin" — coincideix. Descartat Abstract Factory: no hi ha família de productes que hagin de ser coherents entre si.
  6. Filtres: eix de canvi real (tercer tipus al roadmap), dolor present (l'if ja s'ha duplicat en dos llocs). Endavant.

Cas estructural: l'agregador d'opinions

El tiquet: "Integrem les ressenyes d'un agregador extern. El seu SDK retorna ReviewDTO amb getStars() (0-10) i getBody(); el nostre codi de fitxes espera Opinio amb puntuacio() (0-5) i text()."

  1. Problema sense patró: "codi extern correcte, interfície que no encaixa amb la nostra".
  2. Forces: varia el proveïdor extern i la seva interfície; ha de romandre estable el nostre domini (Opinio i tot allò que la consumeix). No volem que ReviewDTO es filtri pel codi.
  3. Família: el dolor és d'encaix d'interfícies → estructural.
  4. Diagnòstic: existeix codi correcte amb la interfície equivocada? Sí, literalment. → Adapter (AdaptadorOpinionsExternes implements Opinio), el mateix moviment que l'AdaptadorPayPal de 03-02.
  5. Validació: descartats Facade (no simplifiquem un subsistema propi, en traduïm un d'aliè) i Decorator (no afegim responsabilitats, convertim interfície).
  6. Filtres: el dolor és immediat (sense adapter, la conversió 0-10 → 0-5 es repetiria a cada punt d'ús). Endavant.

Cas de comportament: la propina al repartidor

El tiquet: "Després del lliurament, el client pot deixar propina. Quan la deixa, cal: abonar-la al repartidor, reflectir-la al seu resum setmanal, sumar-la a les mètriques de la zona i — aviat — disparar-li una notificació d'agraïment."

  1. Problema sense patró: "un fet puntual (propina registrada) interessa un nombre creixent de mòduls que no s'han d'acoblar al que el produeix".
  2. Forces: varia qui hi reacciona (avui tres, demà quatre); ha de romandre estable el registre de la propina. Ningú no dirigeix cap protocol: cada interessat reacciona a allò seu.
  3. Família: el dolor és al flux d'avisos → comportament.
  4. Diagnòstic: molts s'han d'assabentar que un ha canviat? Sí. Hi ha protocol a dirigir entre ells? No. → Observer, reutilitzant la infraestructura d'esdeveniments que ja difon les transicions de la comanda (04-08).
  5. Validació: descartat Mediator amb la prova del cotó de 04-13 — l'emissor no espera coordinació, només que qui vulgui se n'assabenti.
  6. Filtres: el quart interessat ja és al roadmap; sense Observer, registrar la propina acumularia dependències cap a comptabilitat, mètriques i notificacions. Endavant.

Fixa't en el ritme comú: en els tres casos, el patró va ser la conclusió de sis passos, no el punt de partida. I en els tres, hi va haver un descart explícit — saber per què no és el veí val tant com saber per què sí que és l'elegit.

"Espera fins que faci mal"

El mètode té una sortida més, i és la més freqüent en codi sa: encara cap.

Triar patró per endavant — "segur que les promocions acabaran necessitant Interpreter, ho deixo muntat" — és apostar a cegues sobre l'eix de variació futur, i l'aposta gairebé sempre falla: el canvi arriba, però per una altra banda, i l'estructura especulativa fa nosa en comptes d'ajudar. La disciplina professional és la contrària:

  1. Escriu la versió simple (l'if, la crida directa, l'enum) i mantén-la neta.
  2. Anota la intenció si intueixes l'eix de canvi: un comentari "si apareix un tercer tipus de contracte, extreure Factory" costa zero i guia el següent.
  3. Vigila els símptomes: la segona duplicació, el tercer cas del switch, el test que ja no es pot escriure. Aquest és el dolor real.
  4. Quan faci mal, refactoritza cap al patró — que és barat precisament perquè el codi simple és fàcil de moure. Com fer-ho amb xarxa de seguretat és la lliçó 05-04.

La regla de tres és un bon calibrador: la primera vegada escrius directe, la segona dupliques amb càrrec de consciència, la tercera extreus l'abstracció — perquè amb tres casos ja veus l'eix de variació real en comptes d'imaginar-lo. Els patrons es guanyen, no es planten: era la regla d'or de 01-06, i aquest mòdul la converteix en mètode.

Errors Comuns i Consells

  • Començar pel patró ("on uso un Observer?"). És la solució a la recerca de problema. Antídot: obligar-te a escriure la frase del problema sense anomenar patrons; si no surt, encara no hi ha problema.
  • Triar per semblança estructural, no per intenció. Strategy i State comparteixen diagrama; Chain i Decorator també. El diagrama mai no decideix: decideix la intenció, i els acaraments de les comparatives existeixen per a això.
  • Confondre variació de dades amb variació de comportament. Si les variants només canvien valors, un mapa de configuració guanya qualsevol patró.
  • Quedar-se amb el primer candidat. Força sempre un descart explícit ("és X i no Y perquè..."). Si no pots articular el descart, no has acabat el diagnòstic.
  • Oblidar l'opció "cap". L'arbre global té una branca invisible que surt de l'arrel: "el codi simple encara no fa mal → espera". És la branca correcta més vegades de les que l'entusiasme admet.
  • Consell: posa data a les esperes. "Avui no; revisar quan màrqueting llanci el tercer tipus de cupó" converteix la prudència en decisió registrada, no en oblit.

Exercicis

Exercici 1: del tiquet al diagnòstic

Aplica els sis passos del mètode a aquest tiquet de PideYa: "Els restaurants premium volen personalitzar el tiquet que s'imprimeix a cuina: uns hi afegeixen el logo, altres un missatge del xef, altres el desglossament d'al·lèrgens — i qualsevol combinació dels tres. Avui hi ha una subclasse de TicketCuina per combinació i ja en van cinc". Anomena forces, família, candidat, i el patró que has descartat.

Exercici 2: patró o espera?

Per a cada situació, decideix patró concret o espera (amb la versió simple que hi deixaries), justificant-ho amb les forces:

  1. "El càlcul de la comissió aplica un percentatge diferent per tipus de restaurant; els tipus són tres, estables des de fa dos anys, i només difereixen en el número."
  2. "En confirmar una comanda cal avisar cuina. Només cuina. No hi ha res més previst."
  3. "L'estat de la comanda avui és un enum amb switch en quatre mètodes; suport demana afegir l'estat EN_ESPERA_RESTAURANT amb regles pròpies de cancel·lació, i és el segon estat nou aquest any."

Exercici 3: reconstruir el diagnòstic

Un company proposa: "per als cupons de descompte, muntem un Abstract Factory amb una fàbrica per tipus de cupó". Els cupons són: percentatge sobre el total, quantitat fixa, i enviament gratis — un sol objecte cadascun, sense famílies coordinades. Escriu (a) quina pregunta de diagnòstic va fallar en la seva anàlisi, (b) quin candidat surt del mètode ben aplicat, (c) com li ho explicaries sense desautoritzar-lo.

Solucions

Solució 1: (1) Problema: "afegir extres opcionals i combinables al tiquet sense una subclasse per combinació". (2) Forces: varien els afegits i les seves combinacions; estable el tiquet base i la seva interfície. (3) Família: estructural — el dolor és l'explosió de la jerarquia. (4) Diagnòstic: sumar responsabilitats sense tocar la classe, componibles en calent? → Decorator, el mateix moviment que els extres de plat de 03-05. (5) Descart: Template Method fixaria les variants per herència i reproduiria l'explosió combinatòria; Strategy variaria l'algorisme sencer d'impressió, però aquí les peces s'apilen, no se substitueixen. (6) Filtres: cinc subclasses ja fan mal — endavant.

Solució 2: (1) Espera: la variació és de dades (un percentatge), no de comportament — un Map<TipusRestaurant, BigDecimal> o el mateix enum amb un camp ho resol; Strategy seria un embolcall buit. (2) Espera: un sol receptor sense previsió de més — crida directa amb la dependència injectada (DIP, testable), i nota d'intenció "si apareixen més interessats, Observer". Muntar Observer per a un observador és la catedral de l'email de benvinguda. (3) Patró: State — segon estat nou en un any (eix de canvi real i recurrent), regles per estat, switch repetit en quatre mètodes (dolor present). El diagnòstic i la mecànica són a 04-09; com migrar el switch sense trencar res, a 05-04.

Solució 3: (a) Va fallar "hi ha famílies de productes que hagin de ser coherents entre si?" — Abstract Factory paga quan es creen diversos productes coordinats (la FabricaMercat creava passarel·la + impostos + tiquet); aquí cada cupó és un producte solt. (b) Les forces reals: varia l'algorisme de descompte, estable el checkout que l'aplica → Strategy (ReglaDescompte amb tres implementacions), i com a molt un Factory Method simple si la creació des del codi del cupó ho demana. (c) Reconeixent l'encert de l'instint ("has vist bé que la creació no ha de ser al checkout") i reconduint amb la pregunta, no amb la conclusió: "quina família d'objectes coordinats crea cada fàbrica?" — la pregunta correcta deixa que el mateix company arribi al descart.

Conclusió

Ja tens el mètode: problema anomenat sense patrons, forces sobre la taula (què varia, què queda estable), triatge per família, preguntes de diagnòstic, validació contra la intenció amb descart explícit, i els filtres de la balança com a darrer control — amb la sortida "espera fins que faci mal" com a resultat legítim i freqüent. És el mateix camí en cada família, i els tres casos de PideYa ho demostren pas a pas. Però el mètode s'ha entrenat aquí amb problemes d'una sola resposta; el codi real teixeix diversos patrons en una mateixa funcionalitat, i allà les decisions es condicionen les unes a les altres. Veure el mètode funcionant a escala — el flux complet d'una comanda, i un mòdul nou construït des de zero triant cada peça — és la lliçó següent: Exemples Pràctics d'Ús de Patrons.

Curs de Patrons de Disseny de Programari

Mòdul 1: Introducció als Patrons de Disseny

Mòdul 2: Patrons Creacionals

Mòdul 3: Patrons Estructurals

Mòdul 4: Patrons de Comportament

Mòdul 5: Aplicació de Patrons de Disseny

Mòdul 6: Patrons de Disseny Avançats

Mòdul 7: Recursos Addicionals i Conclusió

© Copyright 2026. Tots els drets reservats