Without violating cncapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.(在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。)
备忘录模式介绍
说的直白一点,就是说将一个一个对象进行备份,提供了一种程序数据的备份方法,它的通用类图是:
注意:
- 需要区分对象是深克隆还是浅克隆
备忘录模式分析
缺点:
- 首先来说,使用备忘录代价会比较高:如果原发器在生成备忘录时,必须拷贝并存储大量的信息,或者客户非常频繁地创建备忘录和恢复原发器状态,可能造成很大的开销
- 在某些语言中难以保证只有原发器可访问备忘录的状态
- 维护备忘录的潜在代价会比较高。由于管理器不知道备忘录中有多少个状态,因此存储备忘录时一个原本很小的管理器也可能产生大量的存储
优点:
- 保持封装边界。使用备忘录可以避免暴露一些只应由原发器管理却又必须存储在原发器之外的信息
- 简化了原发器。由于把存储管理的重任交给了Originator,让客户管理它们请求的状态将会简化Originator,并且使得客户工作结束时无需通知原发器
备忘录模式之实现
Golang
Java
那爱情公寓的关谷来举个栗子。首先是关谷类,关谷类记录了关谷当时吵架的心情以及关谷在存档之后的变化:
public class GuanGu{
//吵架时关谷的状态
private String state = "";
//存档后的状态改变
public void changeState(){
this.state = "心情变得冷静下来";
}
public String getState(){
return state;
}
public void setState(String state){
this.state = state;
}
//保留备份
public Memento createMemento(){
return new Memento(this.state);
}
//恢复备份
public void restoreMemento(Memento memento){
this.setState(memento.getState());
}
}
接下来就是比较重要的Memento类了,实现起来极其简单,非常纯粹的JavaBean:
public class Memento{
//关谷的心情
private String state = "";
//通过构造函数传递心情
public Memento(String state){
this.state = state;
}
public String getState(){
return state;
}
public void setState(String state){
this.state = state;
}
}
最后就是备忘录的管理员角色,用来对备忘录进行管理、保存和提供备忘录。备忘录的管理员类也很简单:
public class Caretaker{
//备忘录对象
private Memento memento;
public Memento getMemento(){
return memento;
}
public void setMemento(Memento memento){
this.memento = memento;
}
}
至此,备忘录模式就实现了。
备忘录模式之应用场景
- 需要保存和恢复数据的相关状态场景。
- 提供一个可回滚的操作,比如说各种编辑器中的Ctrl+Z组合键。
- 需要监控的副本场景中。
- 数据库连接的事务管理就是用的备忘录模式。