Also known as Token.
As stated in GoF, p283 :
Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.
That is, create a safe save-state/checkpoint
You should use the Memento pattern in the following cases :
- You want to be able to restore a previous state of an object without exposing the details of its implementation.
- When the existing interface (getters/setters/fields...) of the object would expose implementation details and break its encapsulation.
This is actually pretty straight-forward !
Instead of trying to invade the private space of your objects to copy their states, just delegate creating/restoring snapshots to the actual owner of the state !
As a result, the object creates a Memento object that hides its content from any other class, except the one that produced it.
Note : You can sill provide Memento with a basic interface so that other classes can access its metadata for example, but nothing that would allow to actually modidy its content.
Participants
- Memento :
- Stores internal state of the Originator object.
- May expose an interface to access some metadata of the snapshot.
- Protects against access by objects other than the Originator.
- Originator :
- Creates a Memento containing a snapshot of its current state.
- Uses the Memento to restore itself to a previous state.
- CareTaker :
- Is responsible for the Memento safekeeping.
- Never operates on or examines the contents of a Memento.
How to implement
- Create the Memento class with the set of fields you need to mirror the Originator object.
- Make the Memento class immutable ( do not provide any setter or any other way to modify its fields than its constructor ).
- Optionally, you can Nest the Memento into the Originator object.
- Provide Memento with methods to create Mementos and restore its state from a given Memento.
- Create your Caretaker and provide it with a way to know when requesting new Mementos and when restoring an Originator.
Note : UML class diagram taken from here
Pros
- Preserves encapsulation
- Simplifies Originator by letting the Caretaker maintain the history of its state.
Cons
- Might become memory consuming if too many Mementos are created, or if Mementos are heavy.
- Hidden costs in carring for Mementos - The CareTaker is responsible for managing Mementos lifecycles, but he has no idea how much state is in the Mementos.
Note : Unless encapsulating and restoring Originator state is cheap, you might not want to use the Memento pattern.
Here are some usefull ressources :
- w3sdesign
- A Refactoring guru article.
- A complete example here
