Java设计模式之备忘录模式

 更新时间:2022年10月17日 08:46:19   作者:tianClassmate  
这篇文章介绍了Java设计模式之备忘录模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

无论是我们在使用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 + '\'' +
                '}';
    }
}

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

在基本对象之上,增加保存和撤销的操作,可以看到和我们定义的完稿长的一样,只是又增了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 + '\'' +
                '}';
    }
}

管理员角色(草稿箱):

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

/**
 * 管理者(草稿箱)
 * @author tcy
 * @Date 16-09-2022
 */
public class Caretaker {
    private final Stack<VideoMemento> STACK = new Stack<VideoMemento>();

    public VideoMemento getMemento(){
        VideoMemento videoMemento = STACK.pop();
        return videoMemento;
    }

    public void addMemento(VideoMemento videoMemento){
        STACK.push(videoMemento);
    }
}

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

三、总结

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

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

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

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

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

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • 彻底搞懂Java多线程(三)

    彻底搞懂Java多线程(三)

    这篇文章主要给大家介绍了关于Java面试题之多线程和高并发的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2021-07-07
  • Spring Boot + Spring Batch 实现批处理任务的详细教程

    Spring Boot + Spring Batch 实现批处理任务的详细教程

    这篇文章主要介绍了Spring Boot+Spring Batch实现批处理任务,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • 如何设置Spring Boot测试时的日志级别

    如何设置Spring Boot测试时的日志级别

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。下面我们来一起学习一下吧
    2019-06-06
  • Mybatis如何通过出入Map参数作为条件进行查询

    Mybatis如何通过出入Map参数作为条件进行查询

    这篇文章主要介绍了Mybatis如何通过出入Map参数作为条件进行查询,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java注释和关键字实例详解

    Java注释和关键字实例详解

    注释是对程序语言的说明,有助于开发者和用户之间的交流,方便理解程序,注释不是编程语句,因此被编译器忽略,下面这篇文章主要给大家介绍了关于Java注释和关键字的相关资料,需要的朋友可以参考下
    2023-01-01
  • Java性能优化技巧汇总

    Java性能优化技巧汇总

    这篇文章主要介绍了Java性能优化技巧,汇总了提升java程序性能的常用技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • Eclipse中查看android工程代码出现

    Eclipse中查看android工程代码出现"android.jar has no source attachment

    这篇文章主要介绍了Eclipse中查看android工程代码出现"android.jar has no source attachment"的解决方案,需要的朋友可以参考下
    2016-05-05
  • Java中类的初始化和实例化区别详解

    Java中类的初始化和实例化区别详解

    这篇文章主要介绍了Java中类的初始化和实例化区别详解,类的初始化<BR>是完成程序执行前的准备工作,类的实例化(实例化对象)是指创建一个对象的过程,需要的朋友可以参考下
    2023-08-08
  • Mybatis开发环境搭建实现数据的增删改查功能

    Mybatis开发环境搭建实现数据的增删改查功能

    这篇文章主要介绍了 Mybatis开发环境搭建实现数据的增删改查功能,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-03-03

最新评论