Design pattern learning 21 (Java implementation) — memo pattern

Time:2022-3-15

Write in front

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

Learning address

https://www.bilibili.com/vide…

https://www.bilibili.com/vide…

Reference articles

http://c.biancheng.net/view/1…

Project source code
https://gitee.com/zhuang-kang/DesignPattern

23. Memo mode

23.1 definition and characteristics of intermediary model

Definition of memo mode:Without destroying the encapsulation, capture the internal state of an object and save the state outside the object, so that the object can be restored to the original saved state when necessary in the future.This mode is also called snapshot mode.

Memo mode is an object behavior mode,Its main advantages are as follows.

  • Provides a mechanism to restore state. When users need it, they can easily restore the data to a historical state.
  • The encapsulation of internal state is realized. Except for the initiator who created it, no other object can access this status information.
  • Simplified the human. The initiator does not need to manage and save each backup of its internal status. All status information is saved in the memo and managed by the manager, which is in line with the principle of single responsibility.

Its main disadvantages are:

  • Large 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 memorandum mode

  1. Originator role: record the internal status information at the current time, provide the function of creating memos and recovering memo data, and realize other business functions. It can access all the information in memos.
  2. Memo role: responsible for storing the internal status of the initiator and providing these internal status to the initiator when necessary.
  3. Caretaker role: manages memos and provides the function of saving and obtaining memos, but it cannot access and modify the contents of memos.
  4. The memo has two equivalent interfaces:

    • Narrow interface: the caretaker object (and any object other than other initiator objects) sees the narrow interface of the memo, which only allows him to pass the memo object to other objects.
    • Wide interface: Contrary to the narrow interface seen by the manager, the initiator object can see a wide interface, which allows it to read all the data to restore the internal state of the initiator object according to the data.

23.2.2 code implementation

In a certain scene of the game, a game character has vitality, attack power, defense and other data, which will be different before and after playing boss. We allow players to restore the game to the state before the duel if they feel that the duel with boss is not ideal.

There are two ways to realize the above case:

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

23.2.2.1 white box memo mode

The memo role provides an interface to any object, that is, a wide interface. The internal state stored in the memo role is exposed to all objects

Relational class diagram

Design pattern learning 21 (Java implementation) -- memo pattern

GameRole

package com.zhuang.memento.white_box;

/**
 * @Classname GameRole
 *@ description game character class
 * @Date 2021/3/29 10:14
 * @Created by dell
 */

public class GameRole {

    private int vit;// vitality
    private int atk;// aggressivity
    private int def;// Defensive power

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

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

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

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

    //Display status
    public void stateDisplay() {
        System. out. Println ("role vitality" + VIT);
        System. out. Println ("character attack" + ATK);
        System. out. Println ("character defense" + DEF);
    }

    public int getVit() {
        return vit;
    }

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

    public int getAtk() {
        return atk;
    }

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

    public int getDef() {
        return def;
    }

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

RoleStateMemento

package com.zhuang.memento.white_box;

/**
 * @Classname RoleStateMemento
 *@ description game state storage class memo class
 * @Date 2021/3/29 10:14
 * @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() {
        return vit;
    }

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

    public int getAtk() {
        return atk;
    }

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

    public int getDef() {
        return def;
    }

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

RoleStateCaretaker

package com.zhuang.memento.white_box;

/**
 * @Classname RoleStateCaretaker
 *@ description role status management class
 * @Date 2021/3/29 10:15
 * @Created by dell
 */

public class RoleStateCaretaker {
    private RoleStateMemento roleStateMemento;

    public RoleStateMemento getRoleStateMemento() {
        return roleStateMemento;
    }

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

Client

package com.zhuang.memento.white_box;

/**
 * @Classname Client
 *@ description memo 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 the boss war --------------------------");
        //Before the war with boss
        GameRole gameRole = new GameRole();
        gameRole.initState();
        gameRole.stateDisplay();

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

        System. out. Println ("-------------- after the boss war --------------------------");
        //The boss suffered serious losses during the war
        gameRole.fight();
        gameRole.stateDisplay();

        System. out. Println ("----------------- full blood resurrection ---------------------");
        gameRole.recoverState(roleStateCaretaker.getRoleStateMemento());
        gameRole.stateDisplay();
    }
}

Design pattern learning 21 (Java implementation) -- memo pattern

23.2.2.2 black box memo mode

The memo role provides a wide interface for the initiator object and a narrow interface for other objects. In the Java language, the way to realize the dual interface is toMemo classDesigned asInitiate humanInternal member class of.

takeRoleStateMementoSet asGameRoleThe inner class of theRoleStateMementoObject encapsulated inGameRoleInside; Provide an identification interface on the outsideMementotoRoleStateCaretakerAnd other objects. suchGameRoleClass seesRoleStateMementoAll interfaces, andRoleStateCaretakerAnd other objects only see the identification interfaceMementoThe exposed interface thus maintains the encapsulated type. The class diagram is as follows:

Design pattern learning 21 (Java implementation) -- memo pattern

GameRole

package com.zhuang.memento.black_box;


import com.zhuang.memento.white_box.RoleStateMemento;

/**
 * @Classname GameRole
 *@ description game character class
 * @Date 2021/3/29 10:14
 * @Created by dell
 */

public class GameRole {

    private int vit;// vitality
    private int atk;// aggressivity
    private int def;// Defensive power

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

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

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

    //Restore 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() {
        System. out. Println ("role vitality" + VIT);
        System. out. Println ("character attack" + ATK);
        System. out. Println ("character defense" + DEF);
    }

    public int getVit() {
        return vit;
    }

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

    public int getAtk() {
        return atk;
    }

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

    public int getDef() {
        return def;
    }

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

    //Define the memo inner class rolestatemento internally (the inner class is set to 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() {
            return vit;
        }

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

        public int getAtk() {
            return atk;
        }

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

        public int getDef() {
            return def;
        }

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

Memento

package com.zhuang.memento.black_box;

/**
 * @Classname Memento
 *@ description narrow interface
 * @Date 2021/3/29 10:40
 * @Created by dell
 */

public interface Memento {
}

RoleStateCaretaker

package com.zhuang.memento.black_box;


/**
 * @Classname RoleStateCaretaker
 *@ description role status management class
 * @Date 2021/3/29 10:15
 * @Created by dell
 */

public class RoleStateCaretaker {
    private Memento memento;

    public Memento getMemento() {
        return memento;
    }

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

Client

package com.zhuang.memento.black_box;

/**
 * @Classname Client
 *@ description memo 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 the boss war --------------------------");
        //Before the war with boss
        GameRole gameRole = new GameRole();
        gameRole.initState();
        gameRole.stateDisplay();

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

        System. out. Println ("-------------- after the boss war --------------------------");
        //The boss suffered serious losses during the war
        gameRole.fight();
        gameRole.stateDisplay();

        System. out. Println ("----------------- full blood resurrection ---------------------");
        gameRole.recoverState(roleStateCaretaker.getMemento());
        gameRole.stateDisplay();
    }
}

Design pattern learning 21 (Java implementation) -- memo pattern

23.3 memo mode application scenario

  • Scenes that need to save and restore data, such as the archiving function of intermediate results when playing games.
  • It is necessary to provide a scene that can roll back operations, such as word, Notepad, Photoshop, idea and other software. When editing, press Ctrl + Z, as well as transaction operations in the database.

23.4 notes and details of memo mode

  • Provide users with a recoverable mechanism, which can make it easier for users to return to a certain historical state
  • It realizes the encapsulation of information, so that users do not need to care about saving details
  • There are too many class member variables, which occupy a large amount of resources. Each save will consume a certain amount of memory

Write at the end

  • If my article is useful to you, please give me some, thank you!
  • If you have any questions, please point them out in the comment area!

Recommended Today

RabbitMQ study notes

Table of contents Related concepts RabbitMQ Install RabbitMQ core part Hello World Work Queues release confirmation switch fanout exchange (pub/sub) direct exchange topic exchange dead letter queue delay queue Release Confirmation Advanced The switch receives the message confirmation callback Fallback message to producer when switch is not routable Backup switch other idempotency priority queue lazy […]