java备忘录模式 | 如何记录历史信息

678 阅读5分钟

519951628599605_.pic.jpg

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

欢迎来到今天的学习,今天我们一起来学习下不怎么常用的一种模式-----备忘录模式。多唠叨几句,我本月将会对java的设计模式精讲,欢迎点击头像,关注我的专栏,我会持续更新,加油!

系列文章:

设计模式之单例模式

设计模式之工厂模式

设计模式之建造者模式

设计模式之代理模式

设计模式之访问者模式

设计模式之适配器模式

设计模式之命令者模式

java状态模式 | 随时随地监控状态改变

java观察者模式 | 如何通知事物的变化

...持续更新中

话不多说,进入正题

备忘录模式

相比较其他几种模式而言,备忘录模式不怎么常用。该模式我认为用起来你感觉简单,理解起来也没有那么抽象,所以本节应该是比较简单的一节。

官方定义是:捕获并外部化对象的内部状态,以便以后可以恢复。

可以理解成copy,复制出一套东西,我们程序员最常用的可能就是数据库的备份等。这个备忘录虽然表面字眼称之为备忘录,但是更多的就是理解为“备份模式”。

我们看下简单的类图

image.png

从该图中,我们能看出备忘录模式包含两个关键角色。

  • 原始对象(Originator):除了创建自身所需要的属性和业务逻辑外,还通过提供方法 create() 和 restore(memento) 来保存和恢复对象副本。

  • 备忘录(Memento):用于保存原始对象的所有属性状态,以便在未来进行撤销操作(个人理解,就是备份容器对象,将要备份的东西放到这里)。

下面我们首先来看看上图中 对应的代码实现。,然后再结合业务来实现。首先,我们创建原始对象 Originator,对象中有四个属性,分别是 state 用于显示当前对象状态,name、用来模拟业务属性

public class Originator {
    private String state = "原始对象";  //打印当前状态
    private String name;
    public Originator() {
    }
    //省略get、set方法


    //备份(备忘录)
    public Memento create() {
        return new Memento(name);
    }
    
    //撤销返回
    public void restore(Memento m) {
        this.state = m.getState();
        this.name = m.getName();
    }
   
}

然后,再来创建备忘录对象 Memento,你会发现备忘录对象几乎就和原始对象的属性一模一样。

public class Memento {
    private String state = "从备份对象恢复为原始对象";  //打印当前状态
    private String name;
    public Memento(String name) {
        this.name = name;
    }
    //省略get、set方法
}
public class Demo {
    public static void main(String[] args) {
        Originator originator = new Originator();
        originator.setName("张三");
        System.out.println(originator);
        Memento memento = originator.create();
        originator.setName("李四");
        System.out.println(originator);
        originator.restore(memento);
        System.out.println(originator);
    }
}

下面我们看下具体场景实现

场景及代码实现

比如我们现正在写掘金文章。忽然我的电脑死机了。直接重启了,那我这好不容易快写好的文章怎么办,难道还需要重头再写吗。当然不是

我可以先创建一个 Blog 对象,该对象中包含 掘金ID、title 和 content,分别代表了 Blog 的唯掘金唯一ID、标题和内容;并提供创建备忘录的 createMemento() 和 restore(BlogMemento m) 方法,分别用于创建备忘录和通过备忘录来恢复原始的 Blog 对象。

代码实现

//博客内容实体
public class Blog {
    private long id;
    private String title;
    private String content;
    public Blog(long id, String title) {
        super();
        this.id = id;
        this.title = title;
    }
    //get set 省略
    
    
    public BlogMemento createMemento() {
        BlogMemento m = new BlogMemento(id, title, content);
        return m;
    }
    public void restore(BlogMemento m) {
        this.id = m.getId();
        this.title = m.getTitle();
        this.content = m.getContent();
    }
    
}

然后,再来创建一个 Blog 的备忘录对象 BlogMemento,同样是复制 Blog 所需要的所有属性内容。

public class BlogMemento {
    private final long id;
    private final String title;
    private final String content;
    public BlogMemento(long id, String title, String content) {
        super();
        this.id = id;
        this.title = title;
        this.content = content;
    }
    public long getId() {
        return id;
    }
    public String getTitle() {
        return title;
    }
    public String getContent() {
        return content;
    }
}

这样基于 Blog 对象的备忘录就创建好了。最后,我们依然还是运行一段单元测试代码来看看运行结果。

public class Client {
    public static void main(String[] args) {
        Blog blog = new Blog(1, "java备忘录模式 | 如何记录历史信息");
        blog.setContent("历史信息的记录........");      //原始的文章内容
        System.out.println(blog);
        BlogMemento memento = blog.createMemento();   //创建blog的备忘录
        blog.setContent("修改图片");      //改变内容
        System.out.println(blog);
        blog.restore(memento);       //撤销操作
        System.out.println(blog);    //这时会显示原始的内容
    }
}

大家从代码中可以看出:备忘录模式在频繁需要撤销与恢复的场景中能够发挥很好的作用

总结

备忘录模式也叫快照模式,具体来说,就是通过捕获对象在某一个时刻的对象状态,再将其保存到外部对象,以便在需要的时候恢复对象到指定时刻下的状态。

注意:在使用备忘录模式时,一定不要误认为它就是万能的备份模式,要合理评估对象所使用的内存空间,再确定是否使用备忘录模式。

好了 今天的讲述就到这里,备忘录模式比较简单,就不多赘述。

弦外之音

感谢你的阅读,如果你感觉学到了东西,麻烦您点赞,关注。

我已经将本章收录在专题里,点击下方专题,关注专栏,我会每天发表干货,本月我会持续输入设计模式。

加油! 我们下期再见!