• 设计模式之备忘录模式


    无论是我们在使用word还是记事本,系统都会为我们提供撤销的功能,这几乎是人人都会使用到的功能,而在我们实际开发中,会不会存在一个很复杂的对象,当更改了其中的某一个属性以后,也提供撤销的功能,可以快速恢复到更新前的状态。提供该功能的模式也正是今天的主题——备忘录模式

    一、概念理解

    书上备忘录的解释是,在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

    其实也就是在一个对象之外再额外的增加一个副本对象,每当我们在对象上更改一些属性以后就构建一个副本,并把副本存放在一个队列中,每当回退该对象的时候就从副本中恢复数据。

    很显然需要三个角色:原对象、副本对象、存放副本的队列。

    也即书上的三个角色定义:

    Originator(发起人角色):负责创建一个备忘录,记录自身需要保存的状态,具备状态回滚功能;即原对象。

    Memento(备忘录角色):用于存储Originator的内部状态,且可以防止Originator以外的对象进行访问;即副本对象。

    Caretaker(管理员角色):负责存储、提供管理Memento,无法对Memento的内容进行操作和访问;也即存放副本的队列。

    为了让概念落地,我们基于备忘录模式的思想实现视频草稿箱的功能。

    在这个业务场景中,发起人其实就是编辑视频的编辑器,在这个编辑器中我们能干啥呢?编辑视频、从草稿箱导入、保存到草稿箱。这不是就是发起人角色的作用吗!我们称为编辑草稿。

    备忘录那不就是草稿修改后吗,我们称之为完稿。

    完稿做好了,要存放到一个列表中用于我们快速修复,那当然就是管理员角色。

    基于三个角色我们实现代码。

    二、案例实现

    备忘录角色(完稿):

    就是个基础对象,用于存储数据,视频包含的属性主要是,标题、封面、视频地址

    /**
     * 备忘录(完稿)
     * @author tcy
     * @Date 16-09-2022
     */
    public class VideoMemento {
        private String title;
        private String videoUrl;
        private String imgs;
    
        public VideoMemento(String title, String content, String imgs) {
            this.title = title;
            this.videoUrl = content;
            this.imgs = imgs;
        }
    
        public String getTitle() {
            return title;
        }
    
        public String getContent() {
            return videoUrl;
        }
    
        public String getImgs() {
            return imgs;
        }
    
        @Override
        public String toString() {
            return "ArticleMemento{" +
                    "title='" + title + '\'' +
                    ", content='" + videoUrl + '\'' +
                    ", imgs='" + imgs + '\'' +
                    '}';
        }
    }
    
    • 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

    发起人角色(编辑草稿):

    在基本对象之上,增加保存和撤销的操作,可以看到和我们定义的完稿长的一样,只是又增了saveToMemento()方法和undoFromMemento()方法,用于保存和撤销。

    /**
     * 发起人 (草稿)
     * @author tcy
     * @Date 16-09-2022
     */
    public class Editor {
        private String title;
        private String videoUrl;
        private String imgs;
    
        public Editor(String title, String videoUrl, String imgs) {
            this.title = title;
            this.videoUrl = videoUrl;
            this.imgs = imgs;
        }
    
        public String getTitle() {
            return title;
        }
    
        public String getContent() {
            return videoUrl;
        }
    
        public String getImgs() {
            return imgs;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public void setContent(String content) {
            this.videoUrl = content;
        }
    
        public void setImgs(String imgs) {
            this.imgs = imgs;
        }
    
        /**
         *  保存到备忘录
         * @return
         */
        public VideoMemento saveToMemento(){
            VideoMemento articleMemento = new VideoMemento(this.title,this.videoUrl,this.imgs);
            return articleMemento;
        }
    
        /**
         * 从备忘录恢复
         * @param articleMemento
         */
        public void undoFromMemento(VideoMemento articleMemento){
            this.title = articleMemento.getTitle();
            this.videoUrl = articleMemento.getContent();
            this.imgs = articleMemento.getImgs();
        }
    
        @Override
        public String toString() {
            return "Editor{" +
                    "title='" + title + '\'' +
                    ", content='" + videoUrl + '\'' +
                    ", imgs='" + imgs + '\'' +
                    '}';
        }
    }
    
    • 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

    管理员角色(草稿箱):

    包括一个栈,用于存储完稿,利用栈先进后出的特性,实现逐步的撤销。

    /**
     * 管理者(草稿箱)
     * @author tcy
     * @Date 16-09-2022
     */
    public class Caretaker {
        private final Stack STACK = new Stack();
    
        public VideoMemento getMemento(){
            VideoMemento videoMemento = STACK.pop();
            return videoMemento;
        }
    
        public void addMemento(VideoMemento videoMemento){
            STACK.push(videoMemento);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    读者可以拉取完整代码到本地进行学习,实现代码均测试通过后上传到码云

    三、总结

    备忘录模式是怎么回事想必你已经明白了,如果我们在实际开发中有一个对象的功能很复杂,属性非常的多,这时候备忘录模式就是一个好的选择。

    备忘录模式实现也很简单,在原对象基础之上再增加一个副本对象,在原对象上额外的增加两个方法,用于构建一个副本和从副本中取值。再创建一个栈对象,用于存储、管理副本。

    备忘录模式的优势突出,会简化发起人(原对象)的职责,隔离存储状态,实现信息的封装,客户端无须关心保存细节,而且提供了状态回滚功能。

    但是最显著的缺点就是消耗资源,如果对象改动较大,每一次保存都会消耗很大的内存空间,功能换空间。

    备忘录模式在Jdk和Spring中应用的并不多,在我们实际应用中我们要衡量空间和效率的影响,是否使用备忘录模式进行合理的取舍。

    一、设计模式概述

    二、设计模式之工厂方法和抽象工厂

    三、设计模式之单例和原型

    四、设计模式之建造者模式

    五、设计模式之代理模式

    六、设计模式之适配器模式

    七、设计模式之桥接模式

    八、设计模式之组合模式

    九、设计模式之装饰器模式

    十、设计模式之外观模式

    十一、外观模式之享元模式

    十二、设计模式之责任链模式

    十三、设计模式之命令模式

    十四、设计模式之解释器模式

    十五、设计模式之迭代器模式

    十六、设计模式之中介者模式

  • 相关阅读:
    Zookeeper
    screw 一个简洁好用的数据库表结构文档生成工具
    游戏被攻击了怎么办
    宏的优缺点&&宏的替代技术
    日志审计设计-结合spring-aop实现
    【老生谈算法】matlab实现高斯白噪声仿真算法源码——高斯白噪声
    全国计算机等级考试python(未来教育)
    go get命令不再具有安装功能
    java毕业设计房屋合租系统Mybatis+系统+数据库+调试部署
    Linux 进程和服务管理
  • 原文地址:https://blog.csdn.net/weixin_44643680/article/details/126926814