Memento jest wzorcem, którego wykorzystuje w sytuacji gdy musimy zamrozić stan obiektu w celu jego późniejszego wykonania. Na przykład tak działa Undo. Drugim częstym sposobem na wykorzystanie wzorca memento jest zapamiętywanie wyników zapytań bazy danych w celu ich ponownego późniejszego wykoniania. Zwłaszcza gdy wykonanie zapytań jest bardzo zasobożerne.
Wzorzec memento składa się z trzech głównych obiektów:
- Originator: klasa, której stan ma być przechowywany, musimy w niej implementować metody zapisujące i odczytujące stan z obiektu Memento
- Memento: klasa, w która potrafi przechować wszystkie dane z Originatora, które muszą być utrwalone.
- Caretaker: jest klasą która przechowuje kolekcję memento i udostępnia metody do zapisu i odczytu.
Przypuśmy że mamy klasę (Originator), która ma pole State pole to musi być utrwalane. Tworzymy zatem drugą klasę (Memento) która również posiada pole State. W momencie gdy potrzebujemy utrwalenia wywołujemy metodę saveToMemento Originatora. Metoda ta tworzy obiekt Memento z obecną wartością pola state Originatora. następnie nowo utworzone Memento jest wysyłane do Caretakera w celu utrwalenia.
Zobaczmy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
public class Memento { private String state; public String getSavedState() { return state; } public Memento(String stateToSave) { state = stateToSave; } } public class Originator { private String state; public void setState(String state) { System.out.println("Originator: Setting state to: " + state); this.state = state; } public Memento saveToMemento() { System.out.println("Originator: Saving to Memento"); return new Memento(state); } public void restoreFromMemento(Memento m) { state = m.getSavedState(); System.out.println("Originator: State restored from Memento: " + state); } } public class Caretaker { private List<Memento> savedStates = new ArrayList<Memento>(); public void addMemento(Memento m) { savedStates.add(m); } public Memento getMemento(int index) { return savedStates.get(index); } } public class MementoRunner { public static void main(String[] args) { Caretaker caretaker = new Caretaker(); Originator originator = new Originator(); originator.setState("State 1"); originator.setState("State 2"); caretaker.addMemento(originator.saveToMemento()); originator.setState("State 3"); caretaker.addMemento(originator.saveToMemento()); originator.setState("State 4"); originator.restoreFromMemento(caretaker.getMemento(1)); } } |
Diagram wzorca: