Introducció al Patró Memento
El patró Memento és un patró de disseny de comportament que permet capturar i externalitzar l'estat intern d'un objecte sense violar el seu encapsulament, de manera que l'objecte pugui ser restaurat a aquest estat més tard. Aquest patró és especialment útil quan es necessita implementar funcionalitats de desfer (undo) o historial.
Objectius del Patró Memento
- Capturar l'estat intern d'un objecte: Permet guardar l'estat d'un objecte en un moment determinat.
- Restaurar l'estat: Permet restaurar l'objecte a un estat anterior.
- Encapsulament: Manté l'encapsulament de l'objecte, evitant que altres objectes accedeixin directament al seu estat intern.
Components del Patró Memento
El patró Memento consta de tres components principals:
- Originator: L'objecte que té un estat intern que necessita ser guardat i restaurat.
- Memento: Un objecte que emmagatzema l'estat intern de l'Originator.
- Caretaker: Un objecte que guarda el Memento i el retorna a l'Originator quan es necessita restaurar l'estat.
Diagrama de Classes
+----------------+ +-------------+ +-------------+ | Originator |<----->| Memento |<----->| Caretaker | +----------------+ +-------------+ +-------------+ | - state | | - state | | - memento | | + createMemento() | + getState()| | + addMemento()| | + setMemento() | + setState()| | + getMemento()| +----------------+ +-------------+ +-------------+
Implementació en Codi
A continuació es presenta una implementació del patró Memento en Python:
Originator
class Originator: def __init__(self, state): self._state = state def create_memento(self): return Memento(self._state) def set_memento(self, memento): self._state = memento.get_state() def set_state(self, state): self._state = state def get_state(self): return self._state def __str__(self): return f"Originator(state={self._state})"
Memento
class Memento: def __init__(self, state): self._state = state def get_state(self): return self._state
Caretaker
class Caretaker: def __init__(self): self._mementos = [] def add_memento(self, memento): self._mementos.append(memento) def get_memento(self, index): return self._mementos[index]
Exemple d'Ús
if __name__ == "__main__": originator = Originator("State1") caretaker = Caretaker() # Guardar l'estat inicial caretaker.add_memento(originator.create_memento()) # Canviar l'estat originator.set_state("State2") caretaker.add_memento(originator.create_memento()) # Canviar l'estat novament originator.set_state("State3") print(f"Estat actual: {originator}") # Restaurar l'estat anterior originator.set_memento(caretaker.get_memento(1)) print(f"Estat restaurat: {originator}") # Restaurar l'estat inicial originator.set_memento(caretaker.get_memento(0)) print(f"Estat inicial restaurat: {originator}")
Exercicis Pràctics
Exercici 1: Implementar una Funcionalitat de Desfer
Implementa una funcionalitat de desfer (undo) utilitzant el patró Memento. Crea una classe TextEditor
que permeti afegir text i desfer l'última operació.
Solució
class TextEditor: def __init__(self): self._content = "" self._caretaker = Caretaker() def write(self, text): self._caretaker.add_memento(Memento(self._content)) self._content += text def undo(self): if self._caretaker._mementos: memento = self._caretaker.get_memento(len(self._caretaker._mementos) - 1) self._content = memento.get_state() self._caretaker._mementos.pop() def read(self): return self._content if __name__ == "__main__": editor = TextEditor() editor.write("Hola, ") editor.write("món!") print(editor.read()) # Output: Hola, món! editor.undo() print(editor.read()) # Output: Hola, editor.undo() print(editor.read()) # Output:
Resum
El patró Memento és una solució elegant per capturar i restaurar l'estat d'un objecte sense violar el seu encapsulament. És especialment útil en aplicacions que requereixen funcionalitats de desfer o historial. Amb una comprensió clara dels components i la implementació del patró, es poden crear sistemes més robustos i flexibles.
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