1. 定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
一个备忘录是一个对象,它存储另一个对象在某个瞬间的内部状态,后者被称为备忘录的原发器。
2. 类图
Memento: 备忘录。主要用来存储原发器对象的内部状态,但是具体需要存储哪些数据是由原发器对象来决定的。另外备忘录应该只能由原发器对象来访问它内部的数据,原发器外部的对象不应该访问到备忘录对象的内部数据。
Originator:原发器。使用备忘录来保存某个时刻原发器自身的状态,也可以使用备忘录来恢复内部状态。
Caretaker:备忘录管理者,或者成为备忘录负责人。主要负责保存备忘录对象,但是不能对备忘录对象的内容进行操作或检查。
3. 实例
package com.jerry.designpattern.demo; /** * 备忘录接口 * @author Jerry * @date 2015年2月1日 下午9:18:38 */ public interface FlowAMockMemento { } package com.jerry.designpattern.demo; import java.io.Serializable; /** * * @author Jerry * @date 2015年2月1日 下午9:21:32 */ public class FlowAMock implements Serializable{ /** * 流程名称 */ private String flowName; private int tempResult; private String tempState; public FlowAMock(String flowName) { this.flowName = flowName; } public void runPhaseOne() { this.tempResult = 3; this.tempState = "phase one"; } public void schema1() { this.tempState += ", schema1"; System.out.println(this.tempState + ",now run:" + this.tempResult); this.tempResult += 11; } public void schema2() { this.tempState += ", schema2"; System.out.println(this.tempState + ",now run:" + this.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 = mementoImpl.getTempResult(); this.tempState = mementoImpl.getTempState(); } private class MementoImpl implements FlowAMockMemento, Serializable { 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; } } } package com.jerry.designpattern.demo; /** * * @author Jerry * @date 2015年2月1日 下午9:41:43 */ public class FlowAMockCareTaker { private FlowAMockMemento memento; public void saveMemento(FlowAMockMemento memento) { this.memento = memento; } public FlowAMockMemento retrieveMemento() { return this.memento; } } package com.jerry.designpattern.demo; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * 将对象保存到文件中 * @author Jerry * @date 2015年2月1日 下午10:38:39 */ public class FlowAMockFileCareTaker { public void saveMemento(FlowAMockMemento memento) { ObjectOutputStream output = null; try { output = new ObjectOutputStream( new BufferedOutputStream( new FileOutputStream("FileMemento"))); output.writeObject(memento); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { output.close(); } catch (IOException e) { // TODO Auto-generated catch block output = null; } } } public FlowAMockMemento retrieveMemento() { FlowAMockMemento memento = null; ObjectInputStream in = null; try { in = new ObjectInputStream( new BufferedInputStream( new FileInputStream("FileMemento"))); memento = (FlowAMockMemento) in.readObject(); } catch (Exception e) { // TODO: handle exception try { in.close(); } catch (IOException e1) { // TODO Auto-generated catch block in = null; } } return memento; } } package com.jerry.designpattern.demo; /** * * @author Jerry * @date 2015年2月1日 下午9:53:10 */ public class Client { public static void main(String[] args) { FlowAMock mock = new FlowAMock("TestFlow"); mock.runPhaseOne(); //FlowAMockCareTaker careTaker = new FlowAMockCareTaker(); FlowAMockFileCareTaker careTaker = new FlowAMockFileCareTaker(); careTaker.saveMemento(mock.createMemento()); mock.schema1(); mock.setMemento(careTaker.retrieveMemento()); mock.schema2(); } }
4. 优缺点
优点:更好的封装性,简化了原发器,引入窄接口和款接口。
缺点:可能导致高开销。