Chapter 22 Behavioral Model—Memo Model


Behavioral patterns are used to describe the complex flow control of programs at runtime, that is, to describe how multiple classes or objects cooperate with each other to complete tasks that a single object cannot complete alone. It involves the allocation of responsibilities between algorithms and objects. Behavioral patterns are divided into class behavior patterns and object behavior patterns:

  • Class Behavior Pattern: Use inheritance to distribute behavior between classes

  • Object Behavior Patterns: Distribute behavior among objects using composition or aggregation

Since the combination relationship or aggregation relationship is less coupled than the inheritance relationship and satisfies the "principle of composite reuse", the object behavior pattern has greater flexibility than the class behavior pattern.

Behavioral patterns are divided into:

  • template method pattern
  • strategy pattern
  • command mode
  • chain of responsibility model
  • state mode
  • Observer pattern
  • intermediary pattern
  • iterator pattern
  • visitor mode
  • Memo mode
  • interpreter mode

The above 11 behavioral patterns, except for the template method pattern and the interpreter pattern, which are quasi-behavioral patterns, the others all belong to the object behavioral pattern.

Memo mode

Memo mode : also called snapshot mode, captures the internal state of an object without breaking the encapsulation , and saves this state outside the object , so that the object can be restored to the original saved state when needed later.

Memento pattern is a behavioral design pattern that allows saving and restoring the previous state of an object without exposing its implementation details.

solved problem

The memo mode provides a state recovery mechanism, allowing users to easily return to a specific historical step. When the new state is invalid or there are problems, the state can be restored using temporarily stored memos. Many software provide Undo operation, such as Word, Notepad, Photoshop, IDEA and other software, when you press the Ctrl+Z key combination during editing, you can undo the current operation and restore the document to its previous state; there is also the back key in the browser , the rollback operation in database transaction management, the intermediate result archiving function when playing games, the backup operation of the database and operating system, the regret function in chess games, etc. all belong to this category.

structure

  • Originator: The originator role records the internal state information at the current moment, provides the functions of creating memos and restoring memo data, and realizes other business functions. It can access all information in the memo.

  • Memento: Memento role, responsible for storing the internal state of the initiator and providing these internal states to the initiator when needed.

  • Caretaker: The manager role, manages the memo, provides the function of saving and obtaining the memo, but it cannot access and modify the content of the memo.

Memo has two equivalent interfaces:

Narrow interface: The manager object (and any object other than the initiator object) sees the narrow interface of the memo (narror Interface), which only allows him to pass the memo object to other objects.
Wide Interface: The initiator object can see a wide interface (wide Interface), which allows it to read all the data in order to restore the internal state of the initiator object based on these data.

example

Game Challenge BOSS

In a certain scene in the game, a game character has data such as vitality, attack power, defense power, etc., which must be different before and after fighting the boss. We allow players to restore the game to The state before the duel.

There are two ways to implement the above case:

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

“White box” memo mode

In the white box mode, each memo role 任何对象provides a wide interface, and the state stored inside the memo role is exposed to all objects.

image-20230526130823833

sponsor role

public class GameRole {
    
    
    private int vit;//生命力
    private int atk;//攻击力
    private int def;//防御力
    // 初始化内部状态
    public void initState() {
    
    
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }
    //战斗
    public void fight(){
    
    
        this.vit = 0;
        this.atk = 0;
        this.def = 0;
    }
    //保存角色状态功能
    public RoleStateMemento saveState() {
    
    
        return new RoleStateMemento(vit, atk, def);
    }
    // 恢复角色状态
    public void recoverState(RoleStateMemento roleStateMemento) {
    
    
        // 将备忘录对象中存储的状态赋值给当前对象的成员
        this.vit = roleStateMemento.getVit();
        this.atk = roleStateMemento.getAtk();
        this.def = roleStateMemento.getDef();
    }
    // 展示状态功能
    public void stateDisplay() {
    
    
        System.out.println("角色生命力:" + vit);
        System.out.println("角色攻击力:" + atk);
        System.out.println("角色防御力:" + def);
    }
}

memo role

@Data
@AllArgsConstructor
public class RoleStateMemento {
    
    
    private int vit;//生命力
    private int atk;//攻击力
    private int def;//防御力
}

manager role

@Data
public class RoleStateCaretaker {
    
    
    private RoleStateMemento roleStateMemento;
}

test

public class Client {
    
    
    public static void main(String[] args) {
    
    
        System.out.println("---------------大战boss前-----------------");
        //创建游戏角色对象
        GameRole gameRole = new GameRole();
        gameRole.initState();//初始化状态操作
        gameRole.stateDisplay();
        // 将该游戏角色内部状态进行备份
        // 创建管理者对象
        RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
        roleStateCaretaker.setRoleStateMemento(gameRole.saveState());
        System.out.println("---------------大战boss后-----------------");
        //损耗严重
        gameRole.fight();
        gameRole.stateDisplay();
        System.out.println("---------------恢复之前的状态-----------------");
        gameRole.recoverState(roleStateCaretaker.getRoleStateMemento());
        gameRole.stateDisplay();
    }
}
---------------大战boss前-----------------
角色生命力:100
角色攻击力:100
角色防御力:100
---------------大战boss后-----------------
角色生命力:0
角色攻击力:0
角色防御力:0
---------------恢复之前的状态-----------------
角色生命力:100
角色攻击力:100
角色防御力:100

Analysis: The white box memo pattern destroys encapsulation, but through programmer self-discipline, most of the intentions of the pattern can also be realized to a certain extent.

“Black box” memo mode

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

    • Set RoleStateMemento as the internal class of GameRole, so as to encapsulate the RoleStateMemento object in GameRole; provide an identification interface Memento for RoleStateCaretaker and other objects to use.

    • In this way, the GameRole class sees all the interfaces of RoleStateMemento, while the RoleStateCaretaker and other objects see only the interfaces exposed by the identification interface Memento, thus maintaining the encapsulation.

insert image description here

Memo interface : provides a narrow interface to the outside world, identification interface, no methods

public class Memento {
    
    
}

Initiator role : Game role, defines memo internal class (private) internally RoleStateMemento, provides itself with a wide interface, but cannot be accessed externally

public class GameRole {
    
    
    private int vit;//生命力
    private int atk;//攻击力
    private int def;//防御力
    // 初始化内部状态
    public void initState() {
    
    
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }
    //战斗
    public void fight(){
    
    
        this.vit = 0;
        this.atk = 0;
        this.def = 0;
    }
    //保存角色状态功能
    public Memento saveState() {
    
    
        return new RoleStateMemento(vit, atk, def);
    }
    // 恢复角色状态
    public void recoverState(Memento memento) {
    
    
        //为什么这里j
        RoleStateMemento roleStateMemento = (RoleStateMemento) memento;
        // 将备忘录对象中存储的状态赋值给当前对象的成员
        this.vit = roleStateMemento.getVit();
        this.atk = roleStateMemento.getAtk();
        this.def = roleStateMemento.getDef();
    }
    // 展示状态功能
    public void stateDisplay() {
    
    
        System.out.println("角色生命力:" + vit);
        System.out.println("角色攻击力:" + atk);
        System.out.println("角色防御力:" + def);
    }
    //对发起者宽接口,对其他类窄接口
    @Data
    @AllArgsConstructor
    private static class RoleStateMemento implements Memento {
    
    
        private int vit;//生命力
        private int atk;//攻击力
        private int def;//防御力
    }
}

Manager role : This class aggregates Mementothe interface, which is just an identification interface, so this role cannot change the content of the memo.

@Data
public class RoleStateCaretaker {
    
    
    private Memento memento;
}

Test class

public class Client {
    public static void main(String[] args) {
        System.out.println("---------------大战boos前-----------------");
        // 创建游戏角色对象
        GameRole gameRole = new GameRole();
        gameRole.initState(); // 初始化状态操作
        gameRole.stateDisplay();
        // 将该游戏角色内部状态进行备份
        // 创建管理者对象
        RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
        roleStateCaretaker.setMemento(gameRole.saveState());

        System.out.println("---------------大战boos后-----------------");
        // 损耗严重
        gameRole.fight();
        gameRole.stateDisplay();

        System.out.println("---------------恢复之前的状态-----------------");
        gameRole.recoverState(roleStateCaretaker.getMemento());
        gameRole.stateDisplay();
    }
}

Problems

advantage:

  • Provides a mechanism to restore state. When users need it, they can more easily restore data to a certain historical state.

  • Simplified initiating humans. The initiator does not need to manage and save the backup of its internal state. All state backups are stored in the memorandum and managed by the manager, which conforms to the principle of single responsibility. (Black box mode) realizes the encapsulation of internal state. This state information is not accessible to other objects except the originator who created it.

shortcoming:

  • Resource consumption is large. If there is too much internal state information to be saved or it is very frequent, it will occupy relatively large memory resources.

Applicable scene

Scenarios where data needs to be saved and restored, such as the archiving function of intermediate results when playing games.

It is necessary to provide a rollback operation scenario, such as Word, Notepad, Photoshop, idea and other software, press Ctrl+Z key combination when editing, and transaction operations in the database.

Guess you like

Origin blog.csdn.net/qq_50985215/article/details/130970608