If you ever played any shooter game, you probably know what do hot-keys F5 & F9 mean. If you did not play those anyway you should be aware of usefulness of quick-save/quick-load functionality. By pressing F5 you save your current location your health/armor levels and maybe some other information, like how many monsters did you kill already. This defines your state which is going to be saved. On pressing F9 you return to your previous saved state (kind of undo operation).

When you are saving your state you don’t wanna it to be accessible by other classes (encapsulation of state), so you will be sure that none will decrease you health level. Also you wanna keep track of savings and maybe you are going to add functionality that will get back through two-three saves by pressing Shift+F9 (+F9).

How can you accomplish this?

MEMENTO

Memento pattern is used when you want do undo operations without exposing internal state of the Originator (Game). Coordination of operations is done by Caretaker, or something that simply lists mementos and therefore remembers states without knowing what are they.

Let’s take a look at implementation:

Originator (Game)

public
class
GameOriginator {
    private
GameState _state = new GameState(100, 0);//Health & Killed Monsters


    public void Play(){
        //During
this Play method game’s state is continuously changed

        System.out.print(_state.toString());
        _state = new GameState((int) (_state.Health
* 0.9),
_state.KilledMonsters + 2);
    }

    public
GameMemento gameSave(){
        return
new
GameMemento(_state);
    }

    public void loadGame(GameMemento memento){
        _state = memento.getState();
    }

    public class
GameMemento {
        private
final
GameState _state;
       
        private GameMemento(GameState state) {
            _state = state;
        }

        private GameState getState(){
            return
_state;
        }
    }
}

So it is able to generate memento instance with current game state, as well it is able to get state from existing memento, BUT none else could get that state, since GameMemento is inner class of Game and methods are private.

Caretaker

Or the guy, who keeps track of your F5/F9th. Currently it is able to load the latest one quick save, but it could be easily enhanced.

public
class
Caretaker {
    private
GameOriginator _game;
    private
Stack<GameOriginator.GameMemento> _quickSaves = new Stack<GameOriginator.GameMemento>();

    public
Caretaker() {
        _game = new
GameOriginator();
    }

    public void
shootThatDumbAss(){
        _game.Play();
    }

    public void F5(){
        _quickSaves.push(_game.gameSave());
    }
   
    public void F9(){
        _game.loadGame(_quickSaves.peek());
    }
}

Output

With following usage code:

        Caretaker caretaker = new
Caretaker();
        caretaker.F5();
        caretaker.shootThatDumbAss();

        caretaker.F5();

        caretaker.shootThatDumbAss();
        caretaker.shootThatDumbAss();
        caretaker.shootThatDumbAss();
        caretaker.shootThatDumbAss();

        caretaker.F9();

        caretaker.shootThatDumbAss();

our application generates:

Health: 100
Killed Monsters: 0
Health: 90
Killed Monsters: 2
Health: 81
Killed Monsters: 4
Health: 72
Killed Monsters: 6
Health: 64
Killed Monsters: 8
Health: 90
Killed Monsters: 2

Here is quick UML, that I drew for my example:

My
Design Patterns Table

If you haven't subsribed yet, you can subsribe below: