In this note, I will describe the “Snapshot” or “Memento” pattern.
This pattern refers to the “Behavioral” design patterns.
Suppose we are developing a graphics editor, and we need to add the ability to roll back actions at the user’s command. It is also very important that the system components do not have access to the internal state of the rollback “actions”. When implementing this pattern, the other system components have access only to the object snapshot without the ability to change its internal state, providing a clear, simple external interface. To solve this problem, use the “Snapshot” or “Memento” pattern.
Memento pattern example:
When you click a sprite appears, when you click on a undo button, the action is canceled – the sprite disappears. The example consists of three classes:
- Canvas that shows sprites, user interface.
- Screen controller, it handles input and controls screen logic.
- Canvas states that are saved with each change, and could be are reverted.
In terms of the Snapshot pattern, classes are:
- Canvas – originator, which stated are saved as “mementos”, to revert changes if needed. Originator must revert his state, from memento object if necessary.
- Screen controller – caretaker, this class controls all screen, and know how and when to revert changes.
- Canvas state – memento, which contains state, and some kind of index to track changes correctly.
An important feature of the pattern is that only the Originator should have access to the internal fields of the saved state in the snapshot. Embedded classes are used to implement encapsulation, and in C ++, the ability to specify friend classes is used. Personally, I implemented a simple version without encapsulation for Rise, and using Generic when implementing for Swift. In my version, Memento gives its inner state only to entities of the same class state:
Documentation
https://refactoring.guru/design-patterns/memento
Source code
https://gitlab.com/demensdeum/patterns/