一、模式介绍
备忘录模式,可以在不破坏封装的前提下,捕获和保存一个对象的状态,方便以后在需要的时候,使该对象回到被保存时的状态。备忘录模式为我们提供了一种“后悔药”机制,它同时要求该对象已保存的状态不能被其它对象访问和修改,它主要有以下几种角色组成:
- 发起人(Originator),保存自己当前的状态、负责创建一个备忘录、具有回滚自己状态的能力;
- 备忘录(Memento),用于存储发起人需要被保存的状态,同时需要防止除了发起人之外的人来访问和修改被保存的对象;
- 备忘录管理员(Caretaker),负责存储和管理备忘录,但是要求无法对备忘录的内容进行访问和操作;
备忘录模式的通用写法如下:
/**
* 备忘录抽象接口,在管理员处使用此接口,可以防止其它对象访问和修改被保存对象的状态
*/
public interface IMemento {}
@Data
public class Memento implements IMemento {
private String state;
public Memento(String state){
this.state = state;
}
}
@Data
@Slf4j
public class Originator {
private String state;
/**
* 创建一个当前状态的备忘录
*
* @return
*/
public IMemento createMemento() {
return new Memento(state);
}
/**
* 恢复最近的状态
* @param memento
*/
public void restoreMemento(IMemento memento) {
state = ((Memento)memento).getState();
}
/**
* 展示当前的状态
*/
public void showState() {
log.info("当前的状态为:{}", state);
}
}
public class CareTaker {
private IMemento memento;
public IMemento getMemento(){
return this.memento;
}
public void storeMemento(IMemento memento){
this.memento = memento;
}
}
public class Main {
public static void main(String[] args) {
Originator jack = new Originator();
jack.setState("alive");
jack.showState();
CareTaker admin = new CareTaker();
// 管理员储存当前发起人的状态
admin.storeMemento(jack.createMemento());
// 发起人状态变更
jack.setState("dead");
jack.showState();
// 发起人从管理员处获取先前的状态
jack.restoreMemento(admin.getMemento());
jack.showState();
}
}
二、使用场景
暂无,可以自行实现游戏存档、文档草稿箱等功能。
三、模式总结
3.1 优点
- 简化了发起人的职责,只要做创建备忘录和决定什么时候恢复状态即可,无须再关心保存状态的细节;
- 能提供状态回滚的功能,这是其它模式实现不了的;
3.2 缺点
- 如果需要保存的状态过多,这些状态都会消耗内存,从而导致占用过多的资源;