模式说明
以游戏中的存档和恢复存档为例,在游戏过程中需要保存当前游戏状态(包括各种游戏角色属性)作为存档,在之后的某个时刻能够恢复这个存档。文档中的撤销操作也有类似的需求。此类场景可以用备忘录模式(也叫快照模式)实现。该模式涉及三个角色,发起人类,备忘录类和备忘录管理者类。发起人类管理系统当前状态,并有一个保存为备忘的存档方法,一个恢复为指定备忘版本的恢复存档方法。备忘录类只管理该备忘的状态信息,而备忘录管理者只管理备忘录实例。符合单一职责原则。
本示例客户端中展示备忘录使用过程。声明一个发起者,该发起者设置系统状态后存档。然后创建当前系统存档(备忘录),并让一个备忘录管理者持有。接着该发起者修改系统状态,最后调用存档恢复方法恢复到修改前状态。
结构
发起人类
持有所有状态信息,并有对应的getter/setter
方法。维护一个存档方法createMemento
,返回记录当前系统状态信息的Memento
。另有一个恢复指定存档的方法restoreMomento(Memento m)
,通过参数执行要恢复的Memento
。
备忘录类
管理一个备忘中的系统状态信息。本例中只设置了一个状态信息String state
,通过构造器初始化该state
,并有该state
的getter/setter
。
备忘录管理者类
持有一个备忘录实例,并有该备忘录实例的getter/setter
。
代码演示
package com.yukiyama.pattern.behavior;
/**
* 备忘录模式
*/
public class MementoDemo {
public static void main(String[] args) {
// 声明一个发起者实例
Originator ori = new Originator();
// 设置状态为“Alive”
ori.setState("Alive");
// 初始时状态为"Alive",输出"当前状态为:Alive"
ori.display();
// 声明一个备忘录管理者并让其持有当前memento
MementoManager manager = new MementoManager();
manager.setMemento(ori.CreateMemento());
// 修改ori中的状态为"Dead"
ori.setState("Dead");
// 此时ori中的状态为"Dead",输出"当前状态为:Dead"
ori.display();
// 通过管理者持有的备忘录恢复存档
ori.restoreMemento(manager.getMemento());
// 恢复后状态为存档时的"Alive",输出"当前状态为:Alive"
ori.display();
}
}
/**
* 发起人类
* 持有所有状态信息,并有对应的getter/setter方法。维护一个存档方法
* createMemento,返回记录当前系统状态信息的Memento。另有一个恢复指定
* 存档的方法restoreMomento(Memento m),通过参数执行要恢复的Memento。
*/
class Originator{
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento CreateMemento() {
return new Memento(state);
}
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
public void display() {
System.out.println("当前状态为:" + state);
}
}
/**
* 备忘录类
* 管理一个备忘中的系统状态信息。本例中只设置了一个状态信息String state,
* 通过构造器初始化该state,并有该state的getter/setter。
*/
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;
}
}
/**
* 备忘录管理者类
* 持有一个备忘录实例,并有该备忘录实例的getter/setter。
*/
class MementoManager{
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}