A Memento programtervezési minta biztosítja, hogy egy objektum visszaállítható legyen az előző állapotába.
A Memento minta három objektummal implementálható: originator (kezdeményező), caretaker (gondnok), memento (emlékeztető). Az originator egy objektum, aminek van valamilyen belső állapota. A caretaker valamit módosít az originator belső állapotán, azonban azt akarja, hogy lehetősége legyen visszavonni a változásokat. A caretaker először kér az originator-tól egy memento objektumot. Ezután valamilyen műveletet (vagy műveleteket) végez az originator-on, majd, ha vissza akarja állítani az előző állapotot, akkor visszaadja az originator-nak a memento objektumot. A memento objektum önmagában egy átlátszatlan objektum (a caretaker nem változtathatja meg, vagy nem ajánlott megváltoztatnia). Amikor ezt a mintát használjuk, ügyelni kell arra, hogy ez csak egy objektummal foglalkozik, az originator eközben megváltoztathat más objektumokat vagy erőforrásokat. keretezett|center|UML ábra
Különösen jól használható például visszavonás (undo/redo) funkcionalitás megvalósításakor dokumentumszerkesztés során. Előnye, hogy nem sérti az egységbezárás határait. Hátránya, hogy sokszor erőforrásigényes (pl. teljes dokumentumtartalom mentése, több példányban). Java példa A következő Java program illusztrálja a Memento minta "visszavonás"ának használatát.
import java.util.List; import java.util.ArrayList; class Originator { private String state; // The class could also contain additional data that is not part of the // state saved in the memento..
public void set(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(this.state);
public void restoreFromMemento(Memento memento) { this.state = memento.getSavedState(); System.out.println("Originator: State after restoring from Memento: " + state);
public class Memento { private final String state;
public Memento(String stateToSave) { state = stateToSave;
public String getSavedState() { return state;
class Caretaker { public static void main(String[] args) { List<Originator.Memento> savedStates = new ArrayList<Originator.Memento>();
Originator originator = new Originator(); originator.set("State1"); originator.set("State2"); savedStates.add(originator.saveToMemento()); originator.set("State3"); // We can request multiple mementos, and choose which one to roll back to. savedStates.add(originator.saveToMemento()); originator.set("State4");
originator.restoreFromMemento(savedStates.get(1));
A program kimenete: Originator: Setting state to State1 Originator: Setting state to State2 Originator: Saving to Memento. Originator: Setting state to State3 Originator: Saving to Memento. Originator: Setting state to State4 Originator: State after restoring from Memento: State3
Ez a példa egy Stringet használ állapotként, amelyik egy megváltoztathatatlan objektum Java-ban. Valós életbeli forgatókönyvek esetén az állapot csaknem minden esetben egy objektum lesz és ez esetben az állapot egy példányát kell használni.
Megjegyezzük, hogy megvalósítás rámutat egy hátrányra is: deklarálni kell egy belső osztályt. Jobb lenne, ha a mementó stratégiát egynél több objektumra lehetne alkalmazni.
Leginkább három módja van a mementó elérésének: Szerializáció. Egy osztályt deklarálunk ugyanabban a csomagban. Az objektum egy proxyn keresztül szintén elérhetővé tehető, az adott objektumon egy save/restore (mentés/visszatöltés) műveletén keresztül.
C# Példa A Memento minta lehetővé teszi, hogy rögzítsük egy objektum állapotát az egységbezárás megsértése nélkül, úgy, hogy később vissza tudjuk azt állítani. Itt egy olyan példa látható ahol a memento objektumot konkrétan arra használjuk, hogy visszavonjuk az objektumban történő változásokat: //IVSR : Memento példa C# kód
//eredeti objektum public class OriginalObject
public string String1 { get; set; } public string String2 { get; set; } public Memento MyMemento { get; set; }
public OriginalObject(string str1, string str2)
this.String1 = str1; this.String2 = str2; this.MyMemento = new Memento(str1, str2);
public void Revert()
this.String1 = this.MyMemento.string1; this.String2 = this.MyMemento.string2;
//memento objektum public class Memento
public readonly string string1; public readonly string string2;
public Memento(string str1, string str2)
string1 = str1; string2 = str2;
Jegyzetek
Források További információk
Kapcsolódó szócikkek Programtervezési minta, Viselkedési minta
Kategória:Programtervezési minták Kategória:Java-kódpéldák Kategória:C Sharp-kódpéldák