Memento is one of the Behavioural Design patterns that allows an o*bject to save and restore its previous state* without exposing its internal structure.
This is useful when you want to provide a redo/undo feature in your application, another example will be restoring different commit versions in the repository in git.
Key participants in the memento pattern
Originator: The object whose state needs to be saved.
Memento: An object that acts as a Snapshot of the Originator's state.
CareTaker: The Object responsible for keeping the memento safe, but it does not modify or inspect the state of the memento object.
Originator
public class Originator{
private String state; // could be any data, string, Wrapper classes or custom objects as well
public Originator(){}
public void updateState(String s){
this.state = s;
}
public String getCurrentState(){
return this.state;
}
public Memento saveStateToMemento(){
return new Memento(this.state);
}
public void getStateFromMemento(Memento memento){
this.state = memento.getState();
}
}
Memento
public class Memento {
private String state;
public Memento(String state){
this.state = state;
}
public String getState(){
return this.state;
}
}
CareTake
public class CareTaker {
private List<Memento> mementos;
public CareTaker(){
mementos = new ArrayList<>();
}
public void add(Memento memento){
this.mementos.add(memento);
}
public Memento get(int index){
return this.mementos.get(index);
}
}
Main
public class Main {
public static void main(String args[]){
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();
originator.updateState("state #1");
originator.updateState("state #2");
//save current state in memento and store memento in caretake
careTaker.add(originator.saveStateToMemento());// one state is saved
originator.updateState("state #3");
//save current state in memento and store memento in caretake
careTaker.add(originator.saveStateToMemento());
originator.updateState("state #4");
//current state of originator
System.out.println("current state : "+originator.getCurrentState());
//first snapshot of state
originator.getStateFromMemento(careTaker.get(0));
System.out.println("first snapshot/saved state: "+ originator.getCurrentState());
//second snapshot of state
originator.getStateFromMemento(careTaker.get(1));
System.out.println("second snapshot/saved state: "+originator.getCurrentState());
}
}
Output:
current state: state #4
first snapshot/saved state: state #2
second snapshot/saved state: state #3
Key points
- Similar to the above state (String), any type of state can be wrapped in a memento object and saved in the caretaker list.
- Encapsulation of State: The pattern encapsulates the state and prevents clients from directly manipulating it.
- Undo Mechanism: It helps implement undo/redo operations without revealing the internal workings of the object.
Drawbacks
Memory Usage: Storing states can consume a lot of memory, especially if the object state is large or many states are saved.
Complexity: Managing multiple states can become complex if not designed carefully.
Top comments (0)