[design mode from introduction to mastery] 18 - memo mode

Note source: Shang Silicon Valley Java design pattern (illustration + framework source code analysis)

Memo mode

1. Game character status recovery problem

The game fish color has attack power and defense power. It saves its own state (attack power and defense power) before the war with the Boss. After the war with the Boss, the attack power and defense power decrease and recover from the memo object to the state before the war

Traditional scheme

Traditional scheme problem analysis

  • 1) An object corresponds to an object that saves the object state. In this way, when there are many objects in our game, it is not conducive to management and the cost is also great
  • 2) The traditional method is to simply make a backup, create another object, and then put the data to be backed up into the new object, but this exposes the internal details of the object
  • 3) Solution: memo mode

2. Basic introduction to memo mode

  • 1) Memo pattern: capture the internal state of an object and save the state outside the object without destroying the encapsulation. This will restore the object to its original saved state later
  • 2) The memo mode can be understood as follows: in real life, the memo is used to record something to be done, or to record something that has been agreed, so as not to forget. At the software level, the memo mode has the same meaning. The memo object is mainly used to record a certain state or some data of an object. When fallback is required, the original data can be obtained from the memo object for recovery
  • 3) Memo mode belongs to behavior mode

Schematic class diagram

Sample code

/**
 * Source object
 */
public class Originator {
    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public Memento createMementor() {
        return new Memento(state);
    }

    public void revertStateFromMementor(Memento memento) {
        this.state = memento.getState();
    }
}
/**
 * Memo object
 */
public class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }
}
/**
 * Guardian object
 */
public class Caretaker {
    private List<Memento> mementoList = new ArrayList<>();

    public void addMemento(Memento memento) {
        mementoList.add(memento);
    }

    public Memento getMemento(Integer index) {
        return mementoList.get(index);
    }
}

Test code

Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
originator.setState("Current status:" + " state#1. Blood volume (100 ");
caretaker.addMemento(originator.createMementor());
System.out.println(originator.getState());
originator.setState("Current status:" + " state#2. Blood volume (80 ");
caretaker.addMemento(originator.createMementor());
System.out.println(originator.getState());
originator.setState("Current status:" + " state#3. Blood volume (60 ");
caretaker.addMemento(originator.createMementor());
System.out.println(originator.getState());

// Restore to state 1
originator.revertStateFromMementor(caretaker.getMemento(0));
System.out.println("Recovery status:" + originator.getState());

//Current status: status #1 HP 100
//Current status: status #2 HP 80
//Current status: status #3 HP 60
//Recovery status: current status: status #1 HP 100

Roles and responsibilities in memo mode

  • Originator source object: an object whose state needs to be saved
  • Memo memo object: responsible for saving the internal state of the Originator
  • Caretaker Guardian object: it is responsible for storing multiple Memento objects and using collection management to improve efficiency
  • If you want to save different internal states of multiple Originator objects, you can also use map < string, list < memento > >

3. Memo mode solves the problem of game character status reply

UML class diagram

Memo object

public class Memento {
    private Integer vit;
    private Integer def;

    public Memento(Integer vit, Integer def) {
        this.vit = vit;
        this.def = def;
    }

    public Integer getVit() {
        return vit;
    }

    public void setVit(Integer vit) {
        this.vit = vit;
    }

    public Integer getDef() {
        return def;
    }

    public void setDef(Integer def) {
        this.def = def;
    }
}

Guardian object

public class Caretaker {
    private Memento memento;

    public Memento getMemento() {
        return memento;
    }

    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}

Game character object

public class GameRole {
    private Integer vit;
    private Integer def;

    public Integer getVit() {
        return vit;
    }

    public void setVit(Integer vit) {
        this.vit = vit;
    }

    public Integer getDef() {
        return def;
    }

    public void setDef(Integer def) {
        this.def = def;
    }

    public Memento createMemento() {
        return new Memento(this.vit, this.def);
    }

    public void recoverMemento(Memento memento) {
        this.vit = memento.getVit();
        this.def = memento.getDef();
    }

    public void display() {
        System.out.println("Current attack power of game character:" + this.vit + ",Current defense:" + this.def);
    }
}

Test code

System.out.println("======Pre war state======");
GameRole gameRole = new GameRole();
gameRole.setVit(100);
gameRole.setDef(100);
Caretaker caretaker = new Caretaker();
caretaker.setMemento(gameRole.createMemento());
gameRole.display();

System.out.println("======Post war state======");
gameRole.setVit(10);
gameRole.setDef(10);
gameRole.display();

System.out.println("======Restore from memo object to pre war state======");
gameRole.recoverMemento(caretaker.getMemento());
gameRole.display();

//======Pre war state======
//Game character's current attack power: 100, current defense power: 100
//======Post war state======
//Game character's current attack power: 10, current defense power: 10
//======Restore from memo object to pre war state======
//Game character's current attack power: 100, current defense power: 100

4. Notes and details of memo mode

advantage

  • 1) It provides users with a mechanism to restore the state, which can make it easier for users to return to a historical state
  • 2) The encapsulation of information is realized, so that users do not need to care about the details of state preservation

shortcoming

  • 3) If there are too many member variables of a class, it is bound to occupy a large amount of resources, and each save will consume a certain amount of memory. This should be noted

other

  • 4) Applicable application scenarios:
    1. regret
    2. Archive when playing games
    3. ctrl+z in Windows
    4. Backward in IE
    5. Transaction management of database
  • 5) To save memory, memo mode can be used in conjunction with prototype mode

Keywords: Design Pattern

Added by hismightiness on Sun, 16 Jan 2022 02:52:08 +0200