码迷,mamicode.com
首页 > 其他好文 > 详细

《一天一模式》— 备忘录模式

时间:2020-05-02 09:46:53      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:sch   cursor   oschina   并且   targe   哪些   多个   ctr   width   

一、备忘录模式的概念

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。

二、什么时候使用备忘录模式

备忘录模式也算是设计模式中,几个比较简单的设计模式之一。它的目的是用于保存对象当前的状态,并且在之后可以再次恢复到此状态。

举个例子:就好比文本编辑器软件,每次输入文本后,都可以使用【Ctrl + Z】进行回退。可以想想成每次输入文本后,文本编辑器就保存了一个状态,使用回退可以按照输入顺序进行取消刚才的输入。这就可以理解为备忘录模式的使用场景,当有需要时,保存对象的状态到一个副本中(快照),并提供撤销功能(回退)将当前对象撤销到某个快照中。

三、怎么使用备忘录模式

还是通过一个需求进行描述,项目中需要一个好友列表模块,需要如下功能:

  • 添加好友;
  • 删除好友;
  • 撤回操作;
  • 打印好友信息;

3.1 实现方式

实现类图如下:

技术图片

创建一个Friend对象,用于实现需求要求的功能,并且提供生成备忘录(快照),和回退的功能。

创建一个Memento对象,用于保存Friend中的nameList,这个对象与Friend对象在同一个包下,所以他的访问级别是包访问级别。

具体代码如下:

// 好友列表对象
public class Friend {

    private List<String> nameList = new ArrayList<>();

    // 添加朋友
    public void add(String name) {
        nameList.add(name);
    }

    // 删除朋友
    public void remove(String name) {
        nameList.remove(name);
    }

    // 打印好友列表
    public void print() {
        System.out.println(this.nameList.toString());
    }

    // 创建备忘录
    public Memento createMemento() {
        return new Memento(new ArrayList<>(nameList));
    }

    // 撤回到备忘录
    public void restore(Memento memento) {
        this.nameList = memento.getNameList();
    }

}


/**
 * 备忘录。
 */
public class Memento {

    private List<String> nameList = new ArrayList<>();

    // 构造函数
    // 备忘录与Friend对象在头一个包下,只有Friend可以访问备忘录。
    Memento(List<String> nameList) {
        this.nameList = nameList;
    }

    // 备忘录与Friend对象在头一个包下,只有Friend可以访问备忘录。
    List<String> getNameList() {
        return this.nameList;
    }

}

业务场景如下:

public class Client {

    // 输出
    // [Jack, Mark, Rose]
    // [Jack, Rose]
    // [Jack, Mark, Rose]
    public static void main(String[] args) {
        // 创建好友列表
        Friend friend = new Friend();
        friend.add("Jack");
        friend.add("Mark");
        friend.add("Rose");
        friend.print();
        // 创建备忘录,然后删除一个朋友
        Memento memento = friend.createMemento();
        friend.remove("Mark");
        friend.print();
        // 回退到上次的备忘录
        friend.restore(memento);
        friend.print();
    }

}

3.2 备忘录模式的好处

首先要声明,要实现上面的需求有很多种方式方法,但是为什么选择备忘录模式,这么做有哪些好处,具体如下:

  • 数据安全:Memento对象的访问级别是包级别,也就是说,在这个包之外的对象,是无法操作Memento对象的内部结构的,这样做保证了快照生成后,无法直接修改;
  • 扩展灵活:Friend对象只提供了生成Memento和根据Memento恢复的功能,如何使用Memento全部交给客户端(Client)自己去实现,这种做法可以衍生出很多基于Memento的用法,例如根据时间点保存多个Memento、可以多次撤销Memento或者不仅可以撤销,还可以在撤销的同时做其他操作;

3.3 备忘录模式需要注意的地方

上面的例子中,是将备忘录保存到内存中,如果真正要使用备忘录模式,需要考虑几个问题。

分布式部署

一般线上的操作系统都是分布式部署的,可能创建备忘录和恢复的两次请求会打到不同的两个节点上,这是使用JVM内存就无法做到恢复,所以要考虑将备忘录存储到数据库、文件系统或者分布式缓存中。

持久化

加入我们选择将备忘录保存到数据库、文件系统或者分布式缓存中。那么,当系统升级或者需求变更的过程中,我们修改了备忘录结构,会造成持久化中的备忘录与最新的程序中的备忘录不一致。

基于这一点,需要考虑备忘录的有效期,或者当不一致时的补偿方式。

四、总结

首先总结下使用场景,其实数据库连接的事务管理就是用的备忘录模式:

  • 需要保存和恢复数据的相关状态;
  • 提供一个可回滚(rollback)的操作;

另外,编写备忘录对象时,要灵活使用几种访问修饰符(private protected public),保证备忘录中数据的数据安全。

以上就是我对备忘录模式的一些理解,有不足之处请大家指出,谢谢。

推荐吉安SEO(优化推广)

《一天一模式》— 备忘录模式

标签:sch   cursor   oschina   并且   targe   哪些   多个   ctr   width   

原文地址:https://www.cnblogs.com/vwvwvwgwgvervae/p/12815706.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!