设计模式之备忘录模式

备忘录模式

  • 备忘录模式和原型模式:

    ​ 备忘录模式是保存对象当时的信息 , 而原型模式是调用clone()方法进行对象的克隆 , 所以我认为可以将备忘录模式进行修改 , 保存对象信息可以直接使用clone()克隆对象 , 然后保存到备忘录中 , 但是这就涉及到浅拷贝和深拷贝的问题 , 如果我们的 “发起人类” (Originator) 内部引用类型稍微复杂的话 , 建议不去使用clone()方法 , 而直接进行信息的保存 .

  • 定义:

    ​ 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态 , 这样以后就可以将该对象恢复到原先保存的状态。备忘录模式就像我们大家玩的游戏存档一样 , 当我们打不过BOSS时 , 就可以先保存游戏进度 , 然后再去进行下一步的行动 . 这样方便我们再次从想要的位置开始。

  • 使用场景:

    1. 需要保存一个对象在某一个时刻的状态或部分状态。
    2. 如果用一个接口来让其他对象得到这些状态,将会暴露对象的实现细节并破坏对象的封装性,一个对象不希望外界直接访问其内部状态,通过中间对象可以间接访问其内部状态。
    3. 浏览器回退、数据库备份和恢复、编辑器撤销和还原、虚拟机生成快照和恢复、Git版本控制、棋牌类游戏悔棋等等。
  • UML:

    1. Main:它是一个普通类,可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态,一般将需要保存内部状态的类设计为原发器。
    2. Memento:存储原发器的内部状态,根据原发器来决定保存哪些内部状态。备忘录的设计一般可以参考原发器的设计,根据实际需要确定备忘录类中的属性。需要注意的是,除了原发器本身与负责人类之外,备忘录对象不能直接供其他类使用,原发器的设计在不同的编程语言中实现机制会有所不同。
    3. Gamer:负责人又称为管理者,它负责保存备忘录,但是不能对备忘录的内容进行操作或检查。在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。

在这里插入图片描述

  • 优点:

    1. 它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。
    2. 备忘录实现了对信息的封装,一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。
  • 缺点:

    1. 资源消耗过大,如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。
  • 样例:

    /**
     * 角色备忘录 ;
     */
    public class RoleMemo {
    
        private String name ;
        private String ability ;
    
        public RoleMemo(String name , String ability) {
            this.name = name ;
            this.ability = ability ;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAbility() {
            return ability;
        }
    
        public void setAbility(String ability) {
          this.ability = ability;
        }
    }
    
    /**
     * 角色 ;
     */
    public class Role {
    
        private String name ;
        private String ability ;
    
        @Override
        public String toString() {
            return "角色:" + this.name + "\n" +
                   "能力:" + this.ability ;
        }
    
        /**
         * 保存角色 ;
         * @return
         */
        public RoleMemo saveRole(){
            return new RoleMemo(name , ability) ;
        }
    
        /**
         * 恢复角色 ;
         * @param roleMemo
         */
        public void recoverRole(RoleMemo roleMemo){
            this.name = roleMemo.getName() ;
            this.ability = roleMemo.getAbility() ;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAbility() {
            return ability;
        }
    
        public void setAbility(String ability) {
            this.ability = ability;
        }
    
    }
    
    /**
     * 备忘录管理者 ;
     */
    public class Caretaker {
        private RoleMemo roleMemo ;
    
        public RoleMemo getRoleMemo() {
            return roleMemo;
        }
    
        public void setRoleMemo(RoleMemo roleMemo) {
            this.roleMemo = roleMemo;
        }
    }
    
    public class MemoModeDemo {
    
        public static void main(String[] args) {
            Role role = new Role() ;
            role.setName("钢铁侠");
            role.setAbility("操控钢铁");
    
            System.out.println(role.toString());
    
            Caretaker caretaker = new Caretaker() ;
            caretaker.setRoleMemo(role.saveRole());
    
            role.setName("美国队长");
            role.setAbility("使用盾牌");
    
            System.out.println(role.toString());
    
            role.recoverRole(caretaker.getRoleMemo());
    
            System.out.println(role.toString());
    
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值