Els patrons estructurals són un tipus de patrons de disseny que es centren en com compondre classes i objectes per formar estructures més grans i complexes. Aquests patrons ajuden a garantir que les relacions entre les entitats del sistema siguin flexibles i eficients, permetent una millor gestió del codi i una major facilitat de manteniment.
Objectius dels Patrons Estructurals
- Simplificar les relacions entre objectes: Faciliten la composició d'objectes complexos a partir de components més simples.
- Reduir la complexitat del codi: Mitjançant l'ús de patrons estructurals, es pot reduir la complexitat del codi, fent-lo més fàcil de llegir i mantenir.
- Millorar la reutilització del codi: Permeten reutilitzar components de codi en diferents parts del sistema o en diferents projectes.
- Facilitar l'escalabilitat: Ajuden a crear sistemes que poden créixer i evolucionar de manera més fàcil i controlada.
Tipus de Patrons Estructurals
Els patrons estructurals es poden dividir en diverses categories, cadascuna amb el seu propi propòsit i aplicació. A continuació es presenten els principals patrons estructurals que es tractaran en aquest mòdul:
- Adapter: Permet que classes amb interfícies incompatibles treballin juntes.
- Bridge: Separa l'abstracció de la seva implementació perquè ambdues puguin variar independentment.
- Composite: Composa objectes en estructures d'arbre per representar jerarquies part-tot.
- Decorator: Afegeix funcionalitat addicional a un objecte de manera dinàmica.
- Facade: Proporciona una interfície simplificada a un conjunt de classes o a un subsistema complex.
- Flyweight: Utilitza la compartició per suportar grans quantitats d'objectes petits de manera eficient.
- Proxy: Proporciona un substitut o marcador de lloc per a un altre objecte per controlar l'accés a aquest.
Beneficis dels Patrons Estructurals
- Flexibilitat: Els patrons estructurals permeten canviar l'estructura del sistema sense afectar el seu comportament.
- Mantenibilitat: Faciliten la comprensió i manteniment del codi, ja que les relacions entre objectes estan ben definides.
- Reutilització: Promouen la reutilització de codi, ja que els components poden ser fàcilment combinats i reutilitzats en diferents contextos.
- Escalabilitat: Ajuden a crear sistemes que poden escalar de manera eficient, afegint nous components sense necessitat de canviar els existents.
Exemple Pràctic: Patró Adapter
Per il·lustrar com funciona un patró estructural, considerem el patró Adapter. Aquest patró permet que dues interfícies incompatibles treballin juntes. A continuació es presenta un exemple en codi Java:
// Interfície objectiu interface Target { void request(); } // Classe existent amb una interfície incompatible class Adaptee { void specificRequest() { System.out.println("Request específica"); } } // Classe Adapter que fa compatible Adaptee amb Target class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } @Override public void request() { adaptee.specificRequest(); } } // Client que utilitza la interfície Target public class Client { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); Target target = new Adapter(adaptee); target.request(); // Sortida: Request específica } }
Explicació del Codi
- Interfície Target: Defineix la interfície que el client espera utilitzar.
- Classe Adaptee: Conté la funcionalitat que volem adaptar, però la seva interfície és incompatible amb la que el client espera.
- Classe Adapter: Implementa la interfície Target i conté una instància de Adaptee. En el mètode
request
, crida al mètodespecificRequest
de Adaptee. - Client: Utilitza la interfície Target per interactuar amb Adaptee a través de l'Adapter.
Exercici Pràctic
Exercici 1: Implementar el Patró Adapter
Implementa el patró Adapter per adaptar una classe OldSystem
amb un mètode oldMethod
a una interfície NewSystem
amb un mètode newMethod
.
Solució
// Interfície NewSystem interface NewSystem { void newMethod(); } // Classe OldSystem amb una interfície incompatible class OldSystem { void oldMethod() { System.out.println("Mètode antic"); } } // Classe Adapter que fa compatible OldSystem amb NewSystem class SystemAdapter implements NewSystem { private OldSystem oldSystem; public SystemAdapter(OldSystem oldSystem) { this.oldSystem = oldSystem; } @Override public void newMethod() { oldSystem.oldMethod(); } } // Client que utilitza la interfície NewSystem public class AdapterExample { public static void main(String[] args) { OldSystem oldSystem = new OldSystem(); NewSystem newSystem = new SystemAdapter(oldSystem); newSystem.newMethod(); // Sortida: Mètode antic } }
Explicació de la Solució
- Interfície NewSystem: Defineix la nova interfície que el client espera utilitzar.
- Classe OldSystem: Conté la funcionalitat antiga que volem adaptar.
- Classe SystemAdapter: Implementa la interfície NewSystem i conté una instància de OldSystem. En el mètode
newMethod
, crida al mètodeoldMethod
de OldSystem. - Client: Utilitza la interfície NewSystem per interactuar amb OldSystem a través de SystemAdapter.
Conclusió
Els patrons estructurals són essencials per a la creació de sistemes de programari flexibles i mantenibles. A través de l'ús d'aquests patrons, podem simplificar les relacions entre objectes, millorar la reutilització del codi i facilitar l'escalabilitat dels nostres sistemes. En els següents temes, explorarem cadascun dels patrons estructurals en detall, proporcionant exemples pràctics i exercicis per reforçar els conceptes apresos.
Curs de Patrons de Disseny de Programari
Mòdul 1: Introducció als Patrons de Disseny
- Què són els Patrons de Disseny?
- Història i Origen dels Patrons de Disseny
- Classificació dels Patrons de Disseny
- Avantatges i Desavantatges d'Usar Patrons de Disseny
Mòdul 2: Patrons Creacionals
Mòdul 3: Patrons Estructurals
Mòdul 4: Patrons de Comportament
- Introducció als Patrons de Comportament
- Chain of Responsibility
- Command
- Interpreter
- Iterator
- Mediator
- Memento
- Observer
- State
- Strategy
- Template Method
- Visitor
Mòdul 5: Aplicació de Patrons de Disseny
- Com Seleccionar el Patró Adequat
- Exemples Pràctics d'Ús de Patrons
- Patrons de Disseny en Projectes Reals
- Refactorització Usant Patrons de Disseny
Mòdul 6: Patrons de Disseny Avançats
- Patrons de Disseny en Arquitectures Modernes
- Patrons de Disseny en Microserveis
- Patrons de Disseny en Sistemes Distribuïts
- Patrons de Disseny en Desenvolupament Àgil