美文网首页
设计模式之备忘录模式(Memento)

设计模式之备忘录模式(Memento)

作者: Insecurity | 来源:发表于2021-01-24 01:22 被阅读0次

    概念基础

    • 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。
    • 场景:备份,恢复,工作流回退
    • 推导过程

    1.被存储的对象(假设为Student) ,提供 store,recover 方法
    2.保存的对象 => 引出StudentMemenTo(深浅clone根据业务)
    3.需要有一个对象保存 StudentMemenTo的引用. =>引出 CareTaker
    4.疑问:为什么要构建一个一样的新类,而不是直接返回一个新的clone对象 Student

    • 窄接口:负责人(Caretaker)对象(和其他除发起人之外的任何对象)看到的是备忘录的窄接口(narrow interface),这个窄接口只允许它把备忘录对象传给其他的对象。
    • 宽接口:与负责人对象看到的窄接口相反的是,发起人对象可以看到一个宽接口(wide interface),这个宽接口允许它读取所有的数据,以便根据这些数据恢复对这个发起人对象的内部状态。(限制手段 内部类+空接口,屏蔽负责人对象对备忘录的访问,仅仅作为一个传递作用)

    Session 会话,就可以被当做负责人对象来使用, Spring 工作流中,有应用

    public interface StateManageableMessageContext extends MessageContext {
        Serializable <STRONG>createMessagesMemento</STRONG>();
    
        void<STRONG> restoreMessages</STRONG>(Serializable var1);
    
        void<STRONG> setMessageSource</STRONG>(MessageSource var1);
    }
    
    image.png

    优化,黑盒模式

    • 空接口+内部类 => 屏蔽看守者对备忘录的操作.(最少知道原则)
    • 发起人角色
    package com.dzq.memento.dark;
    
    public class Student {
        private int age ;
        private String name;
        /*保存*/
        public StudentMementoIf store(){
            return new StudentMemento(this);
        }
        /*恢复*/
        public void recover(StudentMementoIf stu){
            /*强制转化为备忘录对象*/
            StudentMemento student = (StudentMemento) stu;
            this.age = student.age;
            this.name = student.name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        /*内部类,仅仅Student本身能够访问*/
        protected class StudentMemento implements StudentMementoIf{
            private int age ;
            private String name;
    
            public StudentMemento(Student student) {
                this.age = student.age;
                this.name = student.name;
            }
    
            public int getAge() {
                return age;
            }
    
            public void setAge(int age) {
                this.age = age;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
        }
    
    
    }
    
    
    • 看守人实现(无法调用备忘录对象的方法)
    package com.dzq.memento.dark;
    
    import com.dzq.memento.PersonMemento;
    
    import java.util.Vector;
    
    /*看守人*/
    public class CareTaker {
        private StudentMementoIf studentMementoIf;
    
        public StudentMementoIf getStudentMementoIf() {
            return studentMementoIf;
        }
    
        public void setStudentMementoIf(StudentMementoIf studentMementoIf) {
            this.studentMementoIf = studentMementoIf;
        }
    }
    
    
    • 备忘录实现的空接口
    package com.dzq.memento.dark;
    
    /*空接口,用于屏蔽管理者对备份类的可见性*/
    public interface StudentMementoIf {
    }
    

    优化二

    • 以上仅仅是简单状态属性,并且只能恢复到上一个节点.如果需要将状态恢复到第N次节点,如何实现?
    • 数组 + index ,可以做到恢复至某个具体的版本.
    package com.dzq.memento.multi_check;
    
    import java.util.Vector;
    /**
     * 常见的软件系统往往存储不止一个状态,而是需要存储多个状态或者叫做有多个检查点
    * */
    public class Message {
        private Vector states;//核心  数组 + current_index
        private int index;
    
        public Vector getStates() {
            return states;
        }
    
        public void setStates(Vector states) {
            this.states = states;
        }
    
        public int getIndex() {
            return index;
        }
    
        public void setIndex(int index) {
            this.index = index;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:设计模式之备忘录模式(Memento)

          本文链接:https://www.haomeiwen.com/subject/hwypzktx.html