Introducció al Patró Flyweight
El patró Flyweight és un patró estructural que té com a objectiu reduir la quantitat de memòria utilitzada per un programa quan es treballa amb un gran nombre d'objectes similars. Aquest patró aconsegueix això compartint parts comunes dels objectes en lloc de mantenir còpies separades per a cada objecte.
Conceptes Clau
- Compartició: El Flyweight permet compartir objectes per reduir l'ús de memòria.
- Estat Intrínsec: Part de l'estat que és compartida entre tots els objectes Flyweight.
- Estat Extrínsec: Part de l'estat que és específica per a cada objecte i no es comparteix.
Estructura del Patró Flyweight
El patró Flyweight es compon de les següents parts:
- Flyweight: Interfície que defineix les operacions que poden ser realitzades per l'objecte Flyweight.
- ConcreteFlyweight: Implementació concreta de l'objecte Flyweight que comparteix l'estat intrínsec.
- FlyweightFactory: Crea i gestiona objectes Flyweight. Assegura que els objectes Flyweight es comparteixin correctament.
- Client: Utilitza els objectes Flyweight i gestiona l'estat extrínsec.
Diagrama UML
+-------------------+ +-------------------+ | Flyweight |<---------| FlyweightFactory| +-------------------+ +-------------------+ | +operation() | | +getFlyweight() | +-------------------+ +-------------------+ ^ | | +-------------------+ |ConcreteFlyweight | +-------------------+ | +operation() | +-------------------+
Implementació en Codi
Exemple en Java
// Flyweight Interface interface Flyweight { void operation(String extrinsicState); } // ConcreteFlyweight class ConcreteFlyweight implements Flyweight { private final String intrinsicState; public ConcreteFlyweight(String intrinsicState) { this.intrinsicState = intrinsicState; } @Override public void operation(String extrinsicState) { System.out.println("Intrinsic State: " + intrinsicState + ", Extrinsic State: " + extrinsicState); } } // FlyweightFactory class FlyweightFactory { private final Map<String, Flyweight> flyweights = new HashMap<>(); public Flyweight getFlyweight(String key) { if (!flyweights.containsKey(key)) { flyweights.put(key, new ConcreteFlyweight(key)); } return flyweights.get(key); } } // Client public class FlyweightPatternDemo { public static void main(String[] args) { FlyweightFactory factory = new FlyweightFactory(); Flyweight flyweight1 = factory.getFlyweight("A"); flyweight1.operation("First Call"); Flyweight flyweight2 = factory.getFlyweight("B"); flyweight2.operation("Second Call"); Flyweight flyweight3 = factory.getFlyweight("A"); flyweight3.operation("Third Call"); } }
Explicació del Codi
- Flyweight Interface: Defineix l'operació
operation
que accepta l'estat extrínsec com a paràmetre. - ConcreteFlyweight: Implementa la interfície Flyweight i manté l'estat intrínsec.
- FlyweightFactory: Gestiona la creació i compartició dels objectes Flyweight. Utilitza un
Map
per emmagatzemar i recuperar els objectes Flyweight. - Client: Utilitza la fàbrica per obtenir objectes Flyweight i invoca les operacions amb l'estat extrínsec.
Exercici Pràctic
Enunciat
Implementa el patró Flyweight per gestionar un sistema de caràcters en un editor de text. Cada caràcter ha de ser un objecte Flyweight que comparteix l'estat intrínsec (el caràcter en si) i té un estat extrínsec (la posició en el text).
Solució
// Flyweight Interface interface CharacterFlyweight { void display(int position); } // ConcreteFlyweight class ConcreteCharacterFlyweight implements CharacterFlyweight { private final char intrinsicState; public ConcreteCharacterFlyweight(char intrinsicState) { this.intrinsicState = intrinsicState; } @Override public void display(int position) { System.out.println("Character: " + intrinsicState + ", Position: " + position); } } // FlyweightFactory class CharacterFlyweightFactory { private final Map<Character, CharacterFlyweight> flyweights = new HashMap<>(); public CharacterFlyweight getFlyweight(char key) { if (!flyweights.containsKey(key)) { flyweights.put(key, new ConcreteCharacterFlyweight(key)); } return flyweights.get(key); } } // Client public class FlyweightPatternTextEditor { public static void main(String[] args) { CharacterFlyweightFactory factory = new CharacterFlyweightFactory(); String text = "HELLO FLYWEIGHT"; for (int i = 0; i < text.length(); i++) { CharacterFlyweight flyweight = factory.getFlyweight(text.charAt(i)); flyweight.display(i); } } }
Explicació de la Solució
- CharacterFlyweight Interface: Defineix l'operació
display
que accepta la posició com a paràmetre. - ConcreteCharacterFlyweight: Implementa la interfície CharacterFlyweight i manté l'estat intrínsec (el caràcter).
- CharacterFlyweightFactory: Gestiona la creació i compartició dels objectes CharacterFlyweight. Utilitza un
Map
per emmagatzemar i recuperar els objectes CharacterFlyweight. - Client: Utilitza la fàbrica per obtenir objectes CharacterFlyweight i invoca les operacions amb la posició del caràcter en el text.
Resum
El patró Flyweight és útil per optimitzar l'ús de memòria en aplicacions que treballen amb un gran nombre d'objectes similars. Compartint l'estat intrínsec i gestionant l'estat extrínsec, aquest patró permet reduir significativament la quantitat de memòria necessària. Hem vist la seva implementació en Java i hem practicat amb un exemple d'un editor de text.
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