Els patrons de comportament se centren en la manera com els objectes interactuen i es comuniquen entre ells. Aquests patrons ajuden a definir com els objectes col·laboren per aconseguir una funcionalitat més gran que la suma de les seves parts individuals. En aquesta secció, explorarem els conceptes bàsics dels patrons de comportament, la seva importància i alguns exemples comuns.
Objectius d'Aprenentatge
Al final d'aquesta secció, hauràs de ser capaç de:
- Comprendre què són els patrons de comportament i per què són importants.
- Identificar els diferents tipus de patrons de comportament.
- Reconèixer situacions en les quals els patrons de comportament poden ser útils.
Què són els Patrons de Comportament?
Els patrons de comportament se centren en la comunicació entre objectes. Aquests patrons ajuden a definir com els objectes col·laboren per aconseguir una funcionalitat més gran que la suma de les seves parts individuals. Els patrons de comportament no només especifiquen com els objectes interactuen, sinó també com es distribueixen les responsabilitats entre ells.
Característiques Clau dels Patrons de Comportament
- Interacció entre Objectes: Defineixen com els objectes es comuniquen i col·laboren per assolir un objectiu comú.
- Distribució de Responsabilitats: Ajuda a distribuir les responsabilitats de manera eficient entre els objectes.
- Flexibilitat i Reutilització: Faciliten la creació de sistemes flexibles i reutilitzables.
Importància dels Patrons de Comportament
Els patrons de comportament són crucials perquè permeten:
- Reduir la Complexitat: Simplifiquen la interacció entre objectes, reduint la complexitat del codi.
- Millorar la Mantenibilitat: Faciliten la modificació i l'extensió del codi sense afectar altres parts del sistema.
- Fomentar la Reutilització: Permeten reutilitzar solucions provades en diferents contextos.
Classificació dels Patrons de Comportament
A continuació, es presenta una llista dels patrons de comportament més comuns que es tractaran en aquest mòdul:
- Chain of Responsibility: Permet que diversos objectes tinguin l'oportunitat de gestionar una sol·licitud passant-la al llarg d'una cadena d'objectes.
- Command: Encapsula una petició com un objecte, permetent així parametritzar els clients amb sol·licituds, cues o registres de sol·licituds.
- Interpreter: Defineix una representació gramatical per a un llenguatge i un intèrpret que utilitza aquesta representació per interpretar frases en el llenguatge.
- Iterator: Proporciona una manera de recórrer els elements d'una col·lecció sense exposar la seva representació subjacent.
- Mediator: Defineix un objecte que encapsula com un conjunt d'objectes interactuen.
- Memento: Permet capturar i externalitzar l'estat intern d'un objecte sense violar l'encapsulació, de manera que l'objecte pugui ser restaurat a aquest estat més tard.
- Observer: Defineix una dependència d'un a molts entre objectes de manera que quan un objecte canvia d'estat, tots els seus dependents són notificats i actualitzats automàticament.
- State: Permet que un objecte alteri el seu comportament quan el seu estat intern canvia.
- Strategy: Defineix una família d'algoritmes, encapsula cada un d'ells i els fa intercanviables.
- Template Method: Defineix l'esquelet d'un algoritme en una operació, diferint alguns passos a subclasses.
- Visitor: Representa una operació que es realitza sobre els elements de l'estructura d'un objecte.
Exemples Pràctics
Exemple 1: Patró Observer
El patró Observer és útil quan tens un objecte (subjecte) que necessita notificar a altres objectes (observadors) sobre canvis en el seu estat. Un exemple comú és un sistema de notificacions.
// Subjecte public class Subject { private List<Observer> observers = new ArrayList<>(); private int state; public int getState() { return state; } public void setState(int state) { this.state = state; notifyAllObservers(); } public void attach(Observer observer){ observers.add(observer); } public void notifyAllObservers(){ for (Observer observer : observers) { observer.update(); } } } // Observador public abstract class Observer { protected Subject subject; public abstract void update(); } // Observador Concret public class ConcreteObserver extends Observer { public ConcreteObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println("State changed to: " + subject.getState()); } } // Ús del Patró public class Main { public static void main(String[] args) { Subject subject = new Subject(); new ConcreteObserver(subject); System.out.println("First state change: 15"); subject.setState(15); System.out.println("Second state change: 10"); subject.setState(10); } }
Exemple 2: Patró Strategy
El patró Strategy permet definir una família d'algoritmes, encapsular-los i fer-los intercanviables. Un exemple comú és un sistema de càlcul de descomptes.
// Estratègia public interface DiscountStrategy { double applyDiscount(double price); } // Estratègia Concreta public class ChristmasDiscount implements DiscountStrategy { @Override public double applyDiscount(double price) { return price * 0.9; } } // Estratègia Concreta public class EasterDiscount implements DiscountStrategy { @Override public double applyDiscount(double price) { return price * 0.8; } } // Context public class ShoppingCart { private DiscountStrategy discountStrategy; public void setDiscountStrategy(DiscountStrategy discountStrategy) { this.discountStrategy = discountStrategy; } public double calculatePrice(double price) { return discountStrategy.applyDiscount(price); } } // Ús del Patró public class Main { public static void main(String[] args) { ShoppingCart cart = new ShoppingCart(); cart.setDiscountStrategy(new ChristmasDiscount()); System.out.println("Price after Christmas discount: " + cart.calculatePrice(100)); cart.setDiscountStrategy(new EasterDiscount()); System.out.println("Price after Easter discount: " + cart.calculatePrice(100)); } }
Exercici Pràctic
Exercici 1: Implementar el Patró Observer
Implementa el patró Observer per a un sistema de notificacions de temperatura. Quan la temperatura canviï, tots els dispositius connectats han de ser notificats.
Solució
// Subjecte public class TemperatureSensor { private List<Device> devices = new ArrayList<>(); private int temperature; public int getTemperature() { return temperature; } public void setTemperature(int temperature) { this.temperature = temperature; notifyAllDevices(); } public void attach(Device device){ devices.add(device); } public void notifyAllDevices(){ for (Device device : devices) { device.update(); } } } // Observador public abstract class Device { protected TemperatureSensor sensor; public abstract void update(); } // Observador Concret public class Phone extends Device { public Phone(TemperatureSensor sensor){ this.sensor = sensor; this.sensor.attach(this); } @Override public void update() { System.out.println("Phone notified. Temperature is: " + sensor.getTemperature()); } } // Ús del Patró public class Main { public static void main(String[] args) { TemperatureSensor sensor = new TemperatureSensor(); new Phone(sensor); System.out.println("Temperature change: 25"); sensor.setTemperature(25); System.out.println("Temperature change: 30"); sensor.setTemperature(30); } }
Conclusió
Els patrons de comportament són essencials per a la creació de sistemes de programari flexibles i mantenibles. Aquests patrons ajuden a definir com els objectes interactuen i col·laboren, distribuint les responsabilitats de manera eficient. En les següents seccions, explorarem cada un dels patrons de comportament en detall, amb 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