备忘录模式
1.定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将改对象恢复到原先保存的状态。
2.示例代码
仿真系统,模拟流程A运行情况的示例
/*模拟运行流程A的对象的备忘录接口,是个窄接口*/ public interface FlowAMockMemento{ //空接口 } /*模拟运行流程A,只是个示意,代指某个具体的流程*/ public class FlowaMock{ //流程名称 private String flowName; //代指某个中间结果,需要外部存储的状态数据 private int tempResult; //代指某个中间状态,需要外部存储的状态数据 private int tempState; //构造方法传入流程名称 public FlowAMock(String flowName){ this.flowName = flowName; } //示意流程运行的第一个阶段 public void runPhaseOne(){ tempResult = 3; tempState = "PhaseOne"; } //示意按照方案一来运行后半流程 public void schema1(){ this.tempState += ",Schema1"; System.out.println(this.tempState + ":now run "+ tempResult); this.tempResult += 11; } //示意按照方案二来运行后半流程 public void schema2(){ this.tempState += ",Schema2"; System.out.println(this.tempState + ":now run "+ tempResult); this.tempResult += 22; } //创建保存原发器对象状态的备忘录对象 public FlowAMockMemento createMemento(){ return new MementoImpl(this.tempResult,this.tempState); } //重新设置原发器对象的状态,让其回到备忘录对象记录的状态 public void setMemento(FlowAMockMemento memento){ MementoImpl mementoImpl = (MementoImpl)memento; this.tempResult = memento.getTempResult(); this.tempState = memento.getTempState(); } //真正备忘录对象,实现备忘录窄接口,实现成私有内部类,不让外部访问 private static class MementoImpl implements FlowAMockMemento{ //示意保存某个中间结果 private int tempResult; private String tempState; public MementoImpl(int tempResult,String tempState){ this.tempResult = tempResult; this.tempState = tempState; } public int getTempResult(){ return tempResult; } public String getTempState(){ return tempState; } } }
/*负责保存模拟运行流程A的对象的备忘录对象*/ public class FlowAMockMementoCareTaker{ //记录被保存的备忘录对象 private FlowAMockMemento memento = null; //保存备忘录对象 public void SaveMemento(FlowAMockMemento memento){ this.memento = memento; } public FlowAMockMemento retriveMemento(){ return memento; } }
/*客户端进行仿真模拟调用*/ public class Client{ public static void maiin(String args[]){ //创建模拟运行流程A的对象 FlowAMock mock = new FlowAMock("TestFlow"); //运行流程的第一个阶段(准备数据) mock.runPhaseOne(); //创建一个管理者 FlowAMementoCareTaker careTaker = new FlowAMementoCareTaker(); //创建此时对象的备忘录对象 FlowAMockMemento memento = mock.createMemento(); careTaker.saveMemento(memento); //按照方案一来运行流程的后半部分 mock.schema1(); //从管理者对象获取备忘录对象,恢复内部状态 mock.setMemento(careTaker.retriveMemento()); //按照方案二来运行流程的后半部分 mock.schema2(); } }
3.实际应用
备忘录模式中,捕获的内部状态存储在备忘录对象中,而备忘录对象通常会被存储在原发器对象之外,也就是被保存状态的对象的外部,通常是存放在管理者对象里边。备忘录模式中,为了控制对象的访问,出现了窄接口和宽接口的概念。窄接口:管理者只能看到备忘录的窄接口,窄接口的实现中通常没有任何方法,只是一个类型标识。窄接口使得管理者只能将备忘录传递给其他对象。宽接口:原发器能看到一个宽接口,允许它访问所需的所有数据,通常实现成为原发器内部一个私有内部类。
备忘录模式的本质:保存和恢复内部状态