• 设计模式-行为型-备忘录模式


    描述

    • 提供一种可以撤销(Undo)恢复到之前状态的实现机制。
    • 捕获并存储一个对象的内部状态,并保持在这个对象之外,以便后期需要时恢复到存储的状态。

    角色

    • 发起人角色:记录当前对象的内部信息,提供创建备忘录和恢复备忘录的功能。
    • 备忘录角色:负责存储发起人角色的内部状态(备份),提供这些内部状态给发起人。
    • 管理者角色:对备忘录进行管理,提供保存和获取备忘录的功能,不对备忘录内容进行修改。
    • 备忘录有两个接口:
      • 窄接口:管理者角色可以看到的,只允许获取备忘录对象,不允许访问备忘录内容。
      • 宽接口:与窄接口相反,发起人可以看到的接口,允许读取和修改备忘录中的内部状态数据。

    实现

    白箱备忘录模式

    • 备忘录角色对所有对象都提供一个接口,即宽接口。内部所存储的状态对所以对象公开。
    • 违背备忘录模式的概念。破坏了封装性
    public class Test {
        public static void main(String[] args) {
            Administration administration = new Administration();
            RoleGame roleGame = new RoleGame();
            roleGame.init();
            System.out.println(roleGame.toString());
            // 备份到管理者角色中
            administration.setBackup(roleGame.saveRo());
            roleGame.rushThroughCustoms();
            System.out.println(roleGame.toString());
            // undo
            roleGame.recovery(administration.getBackup());
            System.out.println(roleGame.toString());
        }
    }
    // 游戏 发起人角色
    class RoleGame{
        // 状态
        private String state;
        // 场景
        private String scene;
    
        // 初始化内部状态
        void init(){
            this.state = "正常状态";
            this.scene = "第一关";
        }
        // 冲关
        void rushThroughCustoms() {
            this.state = "残血状态";
            this.scene = "Boss关卡";
        }
        // 备份角色状态功能
        Backup saveRo() {
            return new Backup(state, scene);
        }
        // 恢复状态
        void recovery(Backup backup) {
            this.state = backup.getState();
            this.scene = backup.getScene();
        }
    
        @Override
        public String toString() {
            return "RoleGame{" +
                    "state='" + state + '\'' +
                    ", scene='" + scene + '\'' +
                    '}';
        }
    }
    // 备忘录角色
    class Backup {
        // 状态
        private String state;
        // 场景
        private String scene;
    
        Backup(String state, String sence) {
            this.state = state;
            this.scene = sence;
        }
    
        public String getScene() {
            return scene;
        }
    
        public String getState() {
            return state;
        }
    }
    // 管理者角色,管理备忘录角色
    // 能去改变备忘录角色,不好
    class Administration{
        // 可以是List,Map等,存储历史上的备忘录
        Backup backup;
    
        public void setBackup(Backup backup) {
            this.backup = backup;
        }
    
        public Backup getBackup() {
            return backup;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    黑箱备忘录模式

    • 备忘录角色对发起人提供一个宽接口,对其它角色提供窄接口。
    • 双重接口的实现办法是,将备忘录角色设计成发起人类的成员内部类。
    public class Test {
        public static void main(String[] args) {
            Administration administration = new Administration();
            RoleGame roleGame = new RoleGame();
            roleGame.init();
            System.out.println(roleGame.toString());
            // 备份到管理者角色中
            administration.setBackupService(roleGame.saveRo());
            roleGame.rushThroughCustoms();
            System.out.println(roleGame.toString());
            // undo
            roleGame.recovery(administration.getBackupService());
            System.out.println(roleGame.toString());
        }
    }
    // 抽象备忘录
    interface BackupService {
    }
    // 游戏 发起人角色
    class RoleGame{
        // 状态
        private String state;
        // 场景
        private String scene;
    
        // 初始化内部状态
        void init(){
            this.state = "正常状态";
            this.scene = "第一关";
        }
        // 冲关
        void rushThroughCustoms() {
            this.state = "残血状态";
            this.scene = "Boss关卡";
        }
        // 备份角色状态功能
        BackupService saveRo() {
            return new BackupServiceImpl(state, scene);
        }
        // 恢复状态
        void recovery(BackupService backup) {
            BackupServiceImpl backupImpl = (BackupServiceImpl)backup;
            this.state = backupImpl.getState();
            this.scene = backupImpl.getScene();
        }
    
        @Override
        public String toString() {
            return "RoleGame{" +
                    "state='" + state + '\'' +
                    ", scene='" + scene + '\'' +
                    '}';
        }
    
        // 具体备忘录
        private class BackupServiceImpl implements BackupService{
            // 状态
            private String state;
            // 场景
            private String scene;
            BackupServiceImpl(String state, String scene) {
                this.state = state;
                this.scene = scene;
            }
    
            public String getState() {
                return state;
            }
    
            public String getScene() {
                return scene;
            }
        }
    }
    
    // 管理者角色,管理备忘录角色。
    // 而且不能去改变备忘录角色
    class Administration{
        // 可以是List,Map等,存储历史上的备忘录
        BackupService backupService;
    
        public BackupService getBackupService() {
            return backupService;
        }
    
        public void setBackupService(BackupService backupService) {
            this.backupService = backupService;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    优点

    • 提供了可以恢复状态的机制(可恢复到某个状态)。
    • 提供了内部状态封装,处理发起人可以访问备忘录,其它对象不能访问发起人的备忘录。(黑箱)
    • 发起人类不需要管理和保存备份,由管理者管理备份,符合单一职责原则。

    缺点

    • 资源消耗大,备份多,频繁备份,将会占用很多内存资源。

    使用场景

    • 需要备份与恢复数据的情况,比如游戏中的存档功能。
    • 需要回滚操作的情况,比如idea,word,要回滚(Ctrl+z)到之前的文本。
  • 相关阅读:
    最近Intelli Idea官方2023
    ThreadLocal详细分析
    【C++】​——多态性与模板(其一)
    MyBatis是什么?使用方式?
    【PID优化】基于蝗虫算法PID控制器优化设计含Matlab源码
    iOS设备管理器iMazing比iTunes好用吗?有哪些优势
    Android Framwork知识学习总结
    3D ToF赋能小米CyberDog 2提升视觉灵敏度
    class MultiScaleRoIAlign(nn.Module):
    Docker的网络模式
  • 原文地址:https://blog.csdn.net/qq_43630812/article/details/126149073