Set patrons estructurals després, toca el mateix que vam fer en tancar els creacionals: posar-los sobre la taula junts, que és on es decideix de debò. I en aquesta família la comparativa és més necessària que en cap altra, perquè quatre dels seus membres —Adapter, Decorator, Facade i Proxy— són mecànicament gairebé indistingibles: un objecte davant d'un altre, delegant. Triar malament entre ells no trenca el programa; trenca una cosa més cara: la comunicació del disseny, perquè el nom del patró és una promesa sobre la intenció, i una promesa equivocada despista tothom qui vingui darrere. Taula general, acarament d'embolcalls, guia de decisió, combinacions i el mapa estructural complet de PideYa: som-hi.

Contingut

  1. Els set, cara a cara
  2. Els quatre embolcalls: mateixa mecànica, intencions diferents
  3. Guia de decisió
  4. Com es combinen entre si
  5. El mapa estructural de PideYa
  6. Errors comuns, exercicis i conclusió

Els set, cara a cara

La taula del panorama de la introducció, ara amb el que hem après: símptoma que el dispara i cost que es paga.

Patró Intenció en una frase Símptoma que el dispara Cost principal
Adapter Traduir la interfície d'una peça intocable a la que el client espera Interfícies incompatibles amb codi aliè/llegat Una classe traductora per adaptee; disciplina de frontera estanca
Bridge Separar abstracció i implementació en dues jerarquies connectades per composició Subclasses amb nom compost (ConfirmacioPush): dos eixos fosos multiplicant-se Disseny a priori; una indirecció; dues jerarquies per mantenir
Composite Tractar uniformement fulles i grups en arbres part-tot El mateix if (esGrup) repetit a cada operació Interfície comuna per consensuar; dilema transparència/seguretat; compte amb els cicles
Decorator Afegir responsabilitats a un objecte embolcallant-lo, combinables en execució Explosió de subclasses per combinacions d'extres opcionals Ceba opaca; moltes classes petites; l'ordre de capes importa
Facade Oferir una porta simple davant d'un subsistema complex La mateixa orquestració copiada en diversos clients Risc d'engreixar-se; temptació de ficar-hi negoci
Flyweight Compartir l'estat intrínsec de multituds d'objectes Milers d'instàncies duplicant dades pesants, memòria mesurada al límit Separar intrínsec/extrínsec complica firmes; exigeix immutabilitat
Proxy Substitut amb la mateixa interfície que controla l'accés al real Objecte car, sensible, remot o repetidament consultat, amb accés sense control Indirecció invisible; fidelitat al contracte; caches per invalidar

Dos eixos transversals per ordenar-los mentalment:

  • Quants objectes organitza? Un davant d'un altre: Adapter, Decorator, Proxy. Molts darrere d'un: Facade (un subsistema), Composite (un arbre), Flyweight (una multitud). Dues jerarquies senceres: Bridge.
  • Canvia la interfície que veu el client? La canvia: Adapter. La simplifica: Facade. La conserva exactament: Decorator, Proxy, Composite (el grup ofereix la de la fulla). La parteix en dues: Bridge. Li és igual: Flyweight (el seu tema és la memòria, no la interfície).

Els quatre embolcalls: mateixa mecànica, intencions diferents

L'acarament estrella. Els quatre comparteixen el gest —rebre crides adreçades a un altre i decidir què fer-ne— i es distingeixen pel que prometen:

Aspecte Adapter Decorator Facade Proxy
Interfície resultant Diferent de la de l'embolcallat (la que el client esperava) La mateixa de l'embolcallat Nova i més simple que les del subsistema La mateixa de l'embolcallat
Què promet Traducció fidel, res més L'embolcallat més responsabilitats visibles El cas d'ús comú sense conèixer les tripes L'embolcallat, amb l'accés vigilat
Altera el comportament observable? No (només l'idioma) Sí: afegeix, i aquesta és la gràcia No afegeix regles: coordina les existents Pot negar-se, posposar o respondre de memòria
Embolcalla... 1 objecte aliè/llegat 1 objecte propi, sovint ja embolcallat (capes) N objectes (el subsistema) 1 objecte propi, normalment el "de debò"
Qui el posa allà? L'integrador, a la frontera El client o qui compon, apilant a la carta L'arquitecte, com a porta del mòdul La infraestructura, sense que el client ho sàpiga
A PideYa AdaptadorPayPal ExtraDobleFormatge, NotificadorAmbReintents FacanaCheckout ProxyImatgePlat, ProxyProteccioGestioComandes

Quatre preguntes en ordre, que resolen el 90% dels dubtes de classificació:

  1. La interfície de fora és una altra que la de dins? → Adapter (si és més simple i n'agrupa diversos, → Facade).
  2. Mateixa interfície: l'embolcall afegeix comportament visible que el client vol i combina? → Decorator.
  3. Mateixa interfície: l'embolcall decideix sobre l'accés (quan, qui, quantes vegades, on) sense que el client hi participi? → Proxy.
  4. Continua el dubte (un logging, unes mètriques)? Ets a la frontera Decorator/Proxy que ja vam treballar a la lliçó de Proxy: decideix per qui ho compon i per a què — capa opcional apilada pel desenvolupador, Decorator; control interposat d'ofici per la infraestructura, Proxy — i documenta la decisió. La frontera existeix; fingir que no, confon més.

Guia de decisió

El flux de preguntes del mòdul sencer. Com la guia creacional: orienta el cas típic, i el filtre previ continua vigent — de debò hi ha símptoma, o estem decorant per esport?

flowchart TD
    A[Problema en compondre<br/>o organitzar objectes] --> B{Es de MEMORIA?<br/>milers d'objectes, dades repetides,<br/>profiler en vermell}
    B -- Si --> FW[Flyweight<br/>intrinsec compartit + fabrica]
    B -- No --> C{L'estructura del domini<br/>es un ARBRE part-tot?}
    C -- Si --> CP[Composite<br/>fulles i grups uniformes]
    C -- No --> D{Una jerarquia creix per<br/>PRODUCTE de dos eixos<br/>independents?}
    D -- Si --> BR[Bridge<br/>abstraccio × implementacio]
    D -- No --> E{El problema es en<br/>UN objecte al qual poso<br/>alguna cosa al davant?}
    E -- No --> F{Molts clients repeteixen<br/>l'orquestracio d'un subsistema?}
    F -- Si --> FC[Facade<br/>porta d'alt nivell]
    F -- No --> Z[Potser no es un problema<br/>estructural: revisa creacionals<br/>o espera al modul 4]
    E -- Si --> G{La seva interficie NO es<br/>la que necessito?}
    G -- Si --> AD[Adapter<br/>traduir a la frontera]
    G -- No --> H{Vull AFEGIR comportament<br/>combinable i visible?}
    H -- Si --> DC[Decorator<br/>capes apilables]
    H -- No --> PX[Proxy<br/>controlar l'acces:<br/>virtual, proteccio, cache, remot]

Consells d'ús, com sempre: les respostes poden ser diverses (un subsistema amb façana pot contenir un composite amb cache darrere d'un proxy); la guia s'aplica per decisió de disseny, no per sistema; i si cap branca no encaixa, la sortida "potser no és estructural" és una resposta legítima — els problemes de comunicació i repartiment de responsabilitats en execució pertanyen al mòdul que ve.

Com es combinen entre si

Com els creacionals, els estructurals treballen en colla. Les combinacions que ja vas veure o olorar a PideYa:

  • Composite + Decorator: comparteixen interfície Component per disseny; un decorador pot embolcallar qualsevol node de l'arbre. Els extres (ExtraDobleFormatge) decoren plats que viuen a la carta Composite; tots dos són, per al client, Producte/ComponentCarta.
  • Composite + Flyweight: les fulles repetides d'un arbre enorme es comparteixen com a flyweights (el GoF ho assenyala expressament); a PideYa, si cada restaurant d'una franquícia repeteix la mateixa carta base, els Plat compartits en són candidats.
  • Proxy + Composite: ProxyCacheCataleg retorna arbres de carta complets: el proxy controla l'accés; el composite estructura allò accedit.
  • Facade sobre tots: FacanaCheckout coordina un subsistema on ja treballen l'Abstract Factory de mercats, el Builder de Comanda, adaptadors de passarel·les i notificadors decorats. La façana no competeix amb ells: els amaga.
  • Adapter dins de Bridge: un implementor concret (CanalWhatsApp) pot ser internament un adaptador de l'SDK del proveïdor. El pont dóna la forma; l'adaptador, la frontera.
  • Decorator/Proxy apilats entre si: logging per fora de reintents, protecció per dins de logging... L'ordre de capes és semàntica (què es registra, què es reintenta): ho vas comprovar als exercicis de totes dues lliçons.
  • Creacionals al servei d'estructurals: les fàbriques munten les estructures — decideixen si lliuren l'objecte real o el seu proxy, componen la pila estàndard de decoradors, trien l'adaptador del mercat. La frase del mòdul 2 continua viva: cada patró governa una capa de la decisió.

El mapa estructural de PideYa

El repàs final del sistema, com vam tancar el mòdul creacional: què va quedar instal·lat, on i per què — amb l'última fila de sempre, la més important.

Part de PideYa Solució estructural Per què aquesta i no una altra
Cobraments amb l'SDK heretat de PayPal Adapter (AdaptadorPayPal implements PassarellaPagament) Interfície aliena i intocable que havia de semblar una passarel·la més; tota la duana en un punt
Catàleg de l'agregador extern Adapter (AdaptadorAgregador) Mateix símptoma, una altra frontera: model de tercers traduït al nostre
Notificacions: tipus × canals Bridge (NotificacioCanalEnviament) Dos eixos independents creixent per producte (9 classes) → creixement additiu (3+3)
La carta del restaurant Composite (ComponentCarta, Plat, SeccioCarta), variant segura Arbre part-tot de profunditat lliure amb operacions uniformes i recursives
Menús i menús niats Composite (Menu, preu recursiu amb descompte) El grup també es ven; allMatch davant d'anyMatch segons el negoci
Extres dels plats Decorator (ExtraPlat: doble formatge, sense gluten, ració gran) Combinatòria opcional decidida per cada client en execució; 3 classes cobreixen 8 combinacions
Reintents i traces de notificadors Decorator tècnic (NotificadorAmbReintents, NotificadorAmbLogging) Responsabilitat transversal, opcional i componible sense tocar els canals
Flux de confirmació de comanda Facade (FacanaCheckout) Orquestració delicada copiada en quatre clients → escrita una vegada darrere d'una porta simple
Seguiment de la comanda a les apps Facade (FacanaSeguiment) Mateix símptoma a escala menor; tipus propis de frontera
Mapa en temps real Flyweight (IconaMarcador + FabricaIcones) 13.000 marcadors repetint ~25 combinacions d'icona: de 400 MB a menys d'1
Fotos dels plats Proxy virtual (ProxyImatgePlat) Objecte car i d'ús escàs: es paga només el que es mira
Permisos del panell intern Proxy de protecció (ProxyProteccioGestioComandes) El qui concentrat en un punt auditable; el servei real, net de seguretat
Consultes de carta massives Proxy de cache (ProxyCacheCataleg) Resposta cara i estable, demanada milers de vegades; invalidació dissenyada alhora
Traces transversals multi-interfície Proxy dinàmic (ManipuladorLogging + java.lang.reflect.Proxy) Un sol handler per a totes les interfícies; el mecanisme dels frameworks
Comandes, cistelles, línies, adreces... Cap Objectes en quantitats normals, interfícies que encaixen, sense eixos multiplicant-se: qualsevol embolcall aquí seria soroll

Aquest és el criteri de maduresa que venim repetint des de la balança: no quants patrons té el sistema, sinó que cadascun sigui on el seu símptoma el va justificar — i que la resta del codi continuï sent simple.

Errors Comuns i Consells

  • Anomenar per mecànica, no per intenció. Dir-ne "proxy" d'un adaptador o "decorador" d'una façana compila igual, però menteix al lector sobre la promesa (tradueix? afegeix? controla?). En aquesta família, el nom del patró és documentació de primera classe: gasta'l bé.
  • Embolcallar per costum. Després d'aquest mòdul, la temptació és posar capes a tot. Cada embolcall és una indirecció que algú depurarà; sense símptoma (interfície que no encaixa, responsabilitat opcional, accés per controlar), la millor estructura és cap.
  • Resoldre amb herència el que aquest mòdul resol amb composició. La subclasse MargaritaSenseGluten o ConfirmacioPush sempre serà a mà i sempre semblarà més ràpida. Recorda les dues explosions (Decorator i Bridge les curen) abans d'heretar la pròxima variant.
  • Triar Bridge quan tocava Adapter, o a l'inrevés. Si les peces ja existeixen i no encaixen: Adapter, i a una altra cosa. Si les jerarquies les dissenyes tu i creixeran per dos eixos: Bridge. Dissenyar "ponts" cap a SDKs aliens o "adaptar" jerarquies pròpies són les dues disfresses del mateix despiste.
  • Façana com a amagatall. Si darrere de la façana el subsistema és un nus, el nus continua creixent — ara sense que ningú no el miri. La façana corona un subsistema sa; no el substitueix.
  • Consell: repeteix aquí l'exercici del mapa que vas fer amb els creacionals: llista cada frontera, cada jerarquia i cada multitud del teu sistema, i anota quin estructural (o quina absència) la governa i per què. Les files sense justificació són les teves candidates a simplificar; les fronteres sense adaptador i les orquestracions copiades, les teves candidates a millorar.

Exercicis

Exercici 1: diagnòstic exprés

Per a cada situació nova a PideYa, tria el patró estructural (o cap) i justifica-ho en una frase amb el seu discriminant:

  1. El servei de facturació d'un partner exigeix rebre les comandes en el seu format EDI, molt diferent del nostre model Comanda.
  2. Els cupons apliquen recàrrecs/descomptes apilables sobre el preu d'una comanda: enviament gratis, -10% primera compra, +0,50 € per hora punta, combinables segons campanya.
  3. Les zones de repartiment s'organitzen en districtes que contenen barris que contenen carrers, i cal saber si una adreça cau en una zona amb recàrrec, a qualsevol nivell.
  4. El nou widget "demana amb un toc" per al mòbil ha de repetir l'última comanda: avui exigeix cridar cinc serveis en ordre.
  5. Cadascun dels 2 milions de clients desa el seu objecte PreferenciesNotificacio, i el 97% té exactament la configuració per defecte.
  6. Volem que el servei de geocodificació només s'instanciï (carrega un índex de 2 GB) si alguna comanda del dia necessita resoldre una adreça nova.

Exercici 2: l'acarament en codi

Sense context, un company troba aquesta classe i pregunta quin patró és. Què li contestes i quina informació addicional demanaries per decidir del tot?

public class ServeiRepartimentVigilat implements ServeiRepartiment {
    private final ServeiRepartiment intern;
    private final Rellotge rellotge;

    @Override
    public AssignacioRepartiment assignar(Comanda comanda) {
        long inici = rellotge.ara();
        AssignacioRepartiment a = intern.assignar(comanda);
        Metriques.registrar("assignar", rellotge.ara() - inici);
        return a;
    }
}

Exercici 3: combinar amb seny

L'equip de partners vol exposar a tercers la consulta de cartes: API pública senzilla, sense revelar el model intern, amb respostes ràpides encara que el catàleg estigui sota càrrega, i sense que un partner sense contracte actiu pugui consultar. Proposa la combinació de patrons estructurals (mínims) i l'ordre en què es travessen en una petició.

Solucions

Solució 1:

  1. Adapter: format aliè i intocable a la frontera; un AdaptadorFacturacioEdi tradueix Comanda → EDI i res més.
  2. Decorator: recàrrecs/descomptes opcionals, apilables i amb ordre significatiu sobre una interfície de preu — la ceba dels extres, en el domini dels cupons.
  3. Composite: part-tot recursiu (districte ⊃ barri ⊃ carrer) amb una operació uniforme (teRecarrec(adreca)), resposta per fulles i propagada per grups.
  4. Facade: orquestració de diversos subsistemes repetida des d'un client més; una FacanaComandaRapida (que per dins reutilitzarà el Prototype de "repetir comanda" del mòdul 2).
  5. Flyweight: multitud (2M) amb estat massivament repetit (97% idèntic i immutable): una instància compartida de les preferències per defecte i objectes propis només per a qui personalitza.
  6. Proxy virtual: objecte caríssim d'instanciar i possiblement no usat; el proxy materialitza el geocodificador al primer ús real.

Solució 2: la resposta curta: "per mecànica és un embolcall amb la mateixa interfície; per intenció, mesurar crides és a la frontera Decorator/Proxy". Informació per decidir: qui el compon i amb quina obligatorietat. Si és la infraestructura qui l'interposa sempre en producció, sense que cap client no el triï (control d'ofici): digues-ne proxy (de mètriques/logging). Si és una capa opcional que cada punt d'ús apila o no, combinant-la amb d'altres (reintents, traces): digues-ne decorador tècnic. També ajuda saber si existeix una família d'embolcalls apilables (fa olor de Decorator) o si aquest és únic i fix davant del servei real (fa olor de Proxy). L'important —digues-li també això— és que la classe està bé: el dubte és d'etiqueta, no de disseny.

Solució 3: tres peces, de fora endins: (1) Facade ApiPublicaCartes: superfície mínima per a partners, amb tipus propis de frontera (res del model intern; l'acarament va ensenyar que interfície nova i més simple sobre un subsistema = façana). (2) Proxy de protecció sobre el servei de catàleg: verifica el contracte actiu del partner i denega registrant (el qui). (3) Proxy de cache (ProxyCacheCataleg, reutilitzat): respostes estables servides de memòria (el quantes vegades). Ordre d'una petició: façana → protecció → cache → catàleg real, que retorna l'arbre Composite de la carta (quarta peça, ja existent, gratis). Protecció abans que cache: un partner morós no ha ni d'escalfar la cache — l'ordre d'embolcalls torna a ser semàntica.

Conclusió

Ja no tens set patrons solts sinó un sistema de decisió: la taula d'intencions i costos, els dos eixos (quants objectes?, què passa amb la interfície?), l'acarament dels quatre embolcalls amb les seves quatre preguntes, el flowchart per al cas típic i les combinacions que apareixen soles quan el disseny va bé. I tens el mapa de PideYa com a demostració de la tesi del curs sencer: cada patró instal·lat on un símptoma concret el va justificar, cap on no — amb la fila "Cap" defensada amb el mateix orgull que les altres.

Amb això, dos terços del catàleg GoF són a la teva caixa d'eines: els creacionals van resoldre el naixement dels objectes; els estructurals, la seva anatomia — com es connecten, embolcallen i organitzen. Queda la tercera pregunta, la més dinàmica de totes: amb els objectes ja creats i ben connectats, com col·laboren en execució? Qui avisa qui quan la comanda canvia d'estat, com es desfà una acció, com recorre la cuina una cua de comandes sense conèixer-ne l'estructura, on viu l'algorisme que decideix el repartiment? Aquesta és la família més nombrosa del catàleg —onze patrons de comportament— i PideYa és plena de converses esperant-los. Ens veiem a la Introducció als Patrons de Comportament.

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