Writing in the front

  • Take notes on learning design patterns
  • Improve the flexible use of design patterns

Learning to address

www.bilibili.com/video/BV1G4…

www.bilibili.com/video/BV1Np…

Refer to the article

C.biancheng.net/view/1317.h…

Program source code

Gitee.com/zhuang-kang…

23. Memo mode

23.1 Definition and characteristics of the intermediary model

The Memento pattern is defined as: ** Without breaking encapsulation, captures the internal state of an object and stores the state outside of the object so that the object can be restored to its original saved state later when needed. ** This mode is also called snapshot mode.

The memo pattern is an object behavior pattern with the following major advantages.

  • Provides a mechanism by which states can be restored. Data can be easily restored to a historical state when the user needs it.
  • Internal state encapsulation is realized. No object other than the originator that created it has access to this state information.
  • Simplified initiation for humans. The sponsor does not need to manage and keep individual copies of its internal state, all state information is kept in memos and managed by the manager, in line with the principle of single responsibility.

Its main disadvantages are:

  • High resource consumption. If the internal state information to be saved is too much or too frequent, it will occupy a large amount of memory resources.

23.2 Structure and implementation of memo mode

23.2.1 Structure of memo mode

  1. Originator: Records internal status information of the current moment, creates memos, restores memo data, and implements other service functions. It can access all information in memos.
  2. Memento role: Responsible for storing the internal state of the initiator and providing this internal state to the initiator when needed.
  3. Caretaker role: Caretaker manages the memo, saves and obtains the memo, but cannot access or modify the memo.
  4. The memo has two equivalent interfaces:
    • Narrow Interface: the Caretaker object (and any other object other than the initiator object) sees the memo’s narror Interface, which only allows the Caretaker to pass the memo object to other objects.
    • Wide Interface: In contrast to the narrow Interface the manager sees, the initiator object sees a wide Interface that allows it to read all data to restore the internal state of the initiator object.

23.2.2 Code implementation

A certain scene in the game, a game character has vitality, attack, defense and other data, before and after the Boss fight will be different, we allow players to feel the effect of the Boss duel is not ideal can be restored to the game before the duel state.

To implement the above case, there are two ways:

  • “White box” memo mode
  • “Black box” memo mode

23.2.2.1 White-box Memo Mode

The memo role provides an interface, or broad interface, to any object, and the state stored inside the memo role is exposed to all objects

Relationship between the class diagram

GameRole

package com.zhuang.memento.white_box;

/ * * *@Classname GameRole
 * @DescriptionGame characters *@Date2021/3/29 "*@Created by dell
 */

public class GameRole {

    private int vit;/ / life
    private int atk;/ / damage
    private int def;/ / defense force

    // Initialization state
    public void initState(a) {
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }

    / / combat
    public void fight(a) {
        this.vit = 0;
        this.atk = 0;
        this.def = 0;
    }

    // Save the role status
    public RoleStateMemento saveState(a) {
        return new RoleStateMemento(vit, atk, def);
    }

    // Restore the role status
    public void recoverState(RoleStateMemento roleStateMemento) {
        this.vit = roleStateMemento.getVit();
        this.atk = roleStateMemento.getAtk();
        this.def = roleStateMemento.getDef();
    }

    // Display status
    public void stateDisplay(a) {
        System.out.println("Character Vitality" + vit);
        System.out.println("Character attack power" + atk);
        System.out.println("Character Defense" + def);
    }

    public int getVit(a) {
        return vit;
    }

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

    public int getAtk(a) {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getDef(a) {
        return def;
    }

    public void setDef(int def) {
        this.def = def; }}Copy the code

RoleStateMemento

package com.zhuang.memento.white_box;

/ * * *@Classname RoleStateMemento
 * @DescriptionGame state storage memos *@Date2021/3/29 "*@Created by dell
 */

public class RoleStateMemento {
    private int vit;
    private int atk;
    private int def;

    public RoleStateMemento(int vit, int atk, int def) {
        this.vit = vit;
        this.atk = atk;
        this.def = def;
    }

    public int getVit(a) {
        return vit;
    }

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

    public int getAtk(a) {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getDef(a) {
        return def;
    }

    public void setDef(int def) {
        this.def = def; }}Copy the code

RoleStateCaretaker

package com.zhuang.memento.white_box;

/ * * *@Classname RoleStateCaretaker
 * @DescriptionRole state management *@Date 2021/3/29 10:15
 * @Created by dell
 */

public class RoleStateCaretaker {
    private RoleStateMemento roleStateMemento;

    public RoleStateMemento getRoleStateMemento(a) {
        return roleStateMemento;
    }

    public void setRoleStateMemento(RoleStateMemento roleStateMemento) {
        this.roleStateMemento = roleStateMemento; }}Copy the code

Client

package com.zhuang.memento.white_box;

/ * * *@Classname Client
 * @DescriptionMemo mode white box test class *@Date 2021/3/29 10:15
 * @Created by dell
 */

public class Client {
    public static void main(String[] args) {
        System.out.println("-------------- before Boss ------------------------");
        // Before the Boss fight
        GameRole gameRole = new GameRole();
        gameRole.initState();
        gameRole.stateDisplay();

        // Save the progress
        RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
        roleStateCaretaker.setRoleStateMemento(gameRole.saveState());

        System.out.println("-------------- after Boss ------------------------");
        // The Boss battle takes a lot of damage
        gameRole.fight();
        gameRole.stateDisplay();

        System.out.println("-------------- Full health resurrect ------------------------"); gameRole.recoverState(roleStateCaretaker.getRoleStateMemento()); gameRole.stateDisplay(); }}Copy the code

23.2.2.2 Black-box Memo Mode

The memo role provides a wide interface to the initiator object and a narrow interface to other objects. In the Java language, the way to achieve dual interfaces is to design the memo class as an internal member class that initiates humans.

Make RoleStateMemento an internal class of GameRole, thus encapsulating the RoleStatemento object inside GameRole; Provide an external identification interface Memento for RoleStateCaretaker and other objects. Thus the GameRole class sees all the interfaces of RoleStateMemento, while RoleStateCaretaker and other objects see only the interfaces exposed by Memento, which identifies the interface, maintaining the encapsulation. The class diagram is as follows:

GameRole

package com.zhuang.memento.black_box;


import com.zhuang.memento.white_box.RoleStateMemento;

/ * * *@Classname GameRole
 * @DescriptionGame characters *@Date2021/3/29 "*@Created by dell
 */

public class GameRole {

    private int vit;/ / life
    private int atk;/ / damage
    private int def;/ / defense force

    // Initialization state
    public void initState(a) {
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }

    / / combat
    public void fight(a) {
        this.vit = 0;
        this.atk = 0;
        this.def = 0;
    }

    // Save the role status
    public Memento saveState(a) {
        return new RoleStateMemento(vit, atk, def);
    }

    // Restore the role status
    public void recoverState(Memento memento) {
        RoleStateMemento roleStateMemento = (RoleStateMemento) memento;
        this.vit = roleStateMemento.getVit();
        this.atk = roleStateMemento.getAtk();
        this.def = roleStateMemento.getDef();
    }

    // Display status
    public void stateDisplay(a) {
        System.out.println("Character Vitality" + vit);
        System.out.println("Character attack power" + atk);
        System.out.println("Character Defense" + def);
    }

    public int getVit(a) {
        return vit;
    }

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

    public int getAtk(a) {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getDef(a) {
        return def;
    }

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

    // Internally define the memo inner class RoleStateMemento (this inner class is set private)

    private class RoleStateMemento implements Memento {
        private int vit;
        private int atk;
        private int def;

        public RoleStateMemento(int vit, int atk, int def) {
            this.vit = vit;
            this.atk = atk;
            this.def = def;
        }

        public int getVit(a) {
            return vit;
        }

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

        public int getAtk(a) {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef(a) {
            return def;
        }

        public void setDef(int def) {
            this.def = def; }}}Copy the code

Memento

package com.zhuang.memento.black_box;

/ * * *@Classname Memento
 * @DescriptionNarrow interface *@Date2021/3/29 10:40: *@Created by dell
 */

public interface Memento {}Copy the code

RoleStateCaretaker

package com.zhuang.memento.black_box;


/ * * *@Classname RoleStateCaretaker
 * @DescriptionRole state management *@Date 2021/3/29 10:15
 * @Created by dell
 */

public class RoleStateCaretaker {
    private Memento memento;

    public Memento getMemento(a) {
        return memento;
    }

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

Client

package com.zhuang.memento.black_box;

/ * * *@Classname Client
 * @DescriptionMemo mode black box test class *@Date 2021/3/29 10:15
 * @Created by dell
 */

public class Client {
    public static void main(String[] args) {
        System.out.println("-------------- before Boss ------------------------");
        // Before the Boss fight
        GameRole gameRole = new GameRole();
        gameRole.initState();
        gameRole.stateDisplay();

        // Save the progress
        RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
        roleStateCaretaker.setMemento(gameRole.saveState());

        System.out.println("-------------- after Boss ------------------------");
        // The Boss battle takes a lot of damage
        gameRole.fight();
        gameRole.stateDisplay();

        System.out.println("-------------- Full health resurrect ------------------------"); gameRole.recoverState(roleStateCaretaker.getMemento()); gameRole.stateDisplay(); }}Copy the code

23.3 Application Scenarios of the Memo Mode

  • Scenarios where data needs to be saved and recovered, such as archiving of intermediate results while playing a game.
  • Need to provide a scenario of rollback operations, such as Word, Notepad, Photoshop, IDEA and other software during editing Ctrl+Z combination key, as well as transaction operations in the database.

23.4 Notes and details of the Memo mode

  • Provide a recovery mechanism for users to easily return to a historical state
  • Information encapsulation is realized, and users do not need to care about saving details
  • Class member variables too many, occupy relatively large resources, each save will consume a certain amount of memory

Write in the last

  • If my article is useful to you, please give me a click 👍, thank you 😊!
  • If you have any questions, please point them out in the comments section! 💪