设计模式之备忘录模式
备忘录模式的简介
在日常生活中,总会出现这样的情况,有时候做错了一件事,然后特别希望能够回到发生这件事情之前。当然,这在日常生活中是不可能,不过,在软件开发过程却是可以实现的,比如说我们经常使用的CTRL + Z,或者一些其他软件的回退功能等等,这其中就涉及到了备忘录模式(Memonto)。所谓的备忘录模式,其实就是把当前对象的一个状态进行保存,然后在必要的时候可以将其恢复,使得对象能够回滚到之前的状态
备忘录模式的具体实现
备忘录模式中,有三个比较重要的概念,一个是目标对象,也就是我们要进行保存的对象,另外一个是备份对象,用于保存目标对象,还有一个是备份对象的管理对象(有时候需要多次备份,此时使用该对象来进行管理是比较合适的)
接下来我们来实现简单的备忘录模式
/**
* Created by Huanfeng.Xu on 2017-06-23.
* 英雄对象
*/
public class Hero {
private String name;
private double power;
// 篇幅原因省略set/get方法
public Memento backup(){
return new Memento(getName(), getPower());
}
public void restore(Memento memento){
setName(memento.getName());
setPower(memento.getPower());
}
}
/**
* Created by Huanfeng.Xu on 2017-06-23.
* 备忘录对象,本质上等同于Hero对象
*/
public class Memento {
private String name;
private double power;
// 篇幅原因,省略set/get方法
}
/**
* Created by Huanfeng.Xu on 2017-06-23.
* CareTaker,用于管理备忘录对象
*/
public class CareTaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
这里需要注意的一点是,虽然这里使用了Memento对象,不过这里我们也看到,本质上它跟Hero对象是一致的,所以,实际上也是可以不需要这个对象,只不过在保存Hero对象的时候需要注意,需要保存的是Hero对象的深拷贝,而不是直接令其指向Hero对象。
在这里一开始会觉得CareTaker对象是多余的,实际上不然,这里我们只保留了一个备份,也就是当下一次进行备份的时候,前面的备份就会被覆盖了,此时,可以在CareTaker对象中提供一个容器类,比如List等,这样子就可以保存多份的备份了,恢复时只需要根据需要恢复特定的备份对象即可,所以说CareTaker对象并不是多余的。
这里需要注意的是,当备份的对象比较多的时候,可能占不少内存,此时,为了节省内存或者其他原因,可以将比较久远的备份持久化到数据库或者本地磁盘中,这样子既有利于对象的长久保留,又有助于节省不必要的内存开销
总结
备忘录模式也是一种比较常用的设计模式,主要用于对象的保存、恢复的相关的操作,比如订单的撤销,回滚等操作,不过需要注意的是,当备份的数量比较多的时候,可能会占据不少内存,此时可以选择将其持久化到磁盘中。