1 基础知识
1.1 标准定义
备忘录(Memento)模式标准定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
1.2 分析和说明
备忘录(Memento)模式属于对象行为型模式。备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。
Memento结构如图1所示,其角色包括发起人(Originator)角色和负责人(Caretaker)角色。
图1 备忘录模式结构
发起人(Originator)角色,发起人角色有如下的责任:①创建一个含有当前的内部状态的备记录对象。②使用备忘录对象存储其内部状态。
负责人(Caretaker)角色,负责人角色有如下的责任:①负责保存备忘录对象。②不检查备忘录对象的内容。
2 应用场景举例
公司领导在每周周一都要召开项目会议,每次会议后都有会议纪要。会议纪要都要把现阶段项目情况汇总起来。这些项目情况就是备忘录,上面有时间戳这个标志。实现用例见图2所示。
图2 备忘录模式用例图
在这里可以把Meeting类理解为发起人(Originator)角色。Caretaker类是负责人(Caretaker)角色。其实现类图如图3所示。Memento类与Caretaker类的关系是聚合关系,即Caretaker类拥有多个Memento类。
图3 备忘录模式类图
备忘录模式实现顺序图见图4,实现顺序描述:
①基于Meeting类创建一个meet1对象;
②调用meet1对象的createMemento方法创建memento对象;
③基于Caretaker类创建一个caretaker对象;
④调用caretaker对象的saveMemento方法,把memento对象存入caretaker对象。
图4 备忘录模式实现顺序图
3.Java的实现程序代码
Java程序实现主要包括Meeting类文件,Caretaker类文件和Memento类文件等3个文件。其关系如图3所示。下面分别列出这3个文件的程序代码,最后列出测试代码并显示输出结果。
Meeting类程序代码清单01所示。
程序代码清单01
public class Meeting { private String meetName; private String meetType; private String meetdate; private String meetLeader; private String meetParticipants; private String decide; private String meetContent; public String getMeetName() { return meetName; } public void setMeetName(String meetName) { this.meetName = meetName; } public String getMeetType() { return meetType; } public void setMeetType(String meetType) { this.meetType = meetType; } public String getMeetdate() { return meetdate; } public void setMeetdate(String meetdate) { this.meetdate = meetdate; } public String getMeetLeader() { return meetLeader; } public void setMeetLeader(String meetLeader) { this.meetLeader = meetLeader; } public String getMeetParticipants() { return meetParticipants; } public void setMeetParticipants(String meetParticipants) { this.meetParticipants = meetParticipants; } public String getDecide() { return decide; } public void setDecide(String decide) { this.decide = decide; } public String getMeetContent() { return meetContent; } public void setMeetContent(String meetContent) { this.meetContent = meetContent; } public void doDecide() { meetContent = "会议名称:" + meetName + ";"; meetContent = meetContent + "会议类型:" + meetType + ";"; meetContent = meetContent + "会议时间:" + meetdate + ";"; meetContent = meetContent + "会议主持人:" + meetLeader + ";"; meetContent = meetContent + "会议参加者:" + meetParticipants + "\r"; meetContent = meetContent + "会议内容:" + meetParticipants + ";"; } public Memento createMemento() { Memento mo = new Memento(meetName, meetType, meetdate, meetLeader, meetParticipants, decide, meetContent); return mo; } public void recoveryMemento(Memento mo) { meetName = mo.getMeetName(); meetType = mo.getMeetType(); meetdate = mo.getMeetdate(); meetLeader = mo.getMeetLeader(); meetParticipants = mo.getMeetParticipants(); decide = mo.getDecide(); meetContent = mo.getMeetContent(); } public void showContent() { System.out.println(meetContent); } } |
Caretaker类程序代码清单02所示。
程序代码清单02
public class Caretaker { private Map<String, Memento> meetMementoMap = new HashMap<String, Memento>(); public Memento recoveryMemento(String meetdate) { return meetMementoMap.get(meetdate); } public void saveMemento(String meetdate, Memento memento) { this.meetMementoMap.put(meetdate, memento); } public void showContent() { System.out.println("显示全部的会议情况:"); String meetdate; String meetContent; Iterator<String> it = meetMementoMap.keySet().iterator(); while (it.hasNext()) { meetdate = it.next(); meetContent = meetMementoMap.get(meetdate).getMeetContent(); System.out.print(meetdate + ";" + meetContent); System.out.println(); } } } |
Memento类程序代码清单03所示。
程序代码清单03
public class Memento { private String meetName; private String meetType; private String meetdate; private String meetLeader; private String meetParticipants; private String decide; private String meetContent; public Memento(String meetName, String meetType, String meetdate, String meetLeader, String meetParticipants, String decide, String meetContent) { super(); this.meetName = meetName; this.meetType = meetType; this.meetdate = meetdate; this.meetLeader = meetLeader; this.meetParticipants = meetParticipants; this.decide = decide; this.meetContent = meetContent; } public void showContent() { System.out.println(meetContent); } public String getMeetName() { return meetName; } public void setMeetName(String meetName) { this.meetName = meetName; } public String getMeetType() { return meetType; } public void setMeetType(String meetType) { this.meetType = meetType; } public String getMeetdate() { return meetdate; } public void setMeetdate(String meetdate) { this.meetdate = meetdate; } public String getMeetLeader() { return meetLeader; } public void setMeetLeader(String meetLeader) { this.meetLeader = meetLeader; } public String getMeetParticipants() { return meetParticipants; } public void setMeetParticipants(String meetParticipants) { this.meetParticipants = meetParticipants; } public String getDecide() { return decide; } public void setDecide(String decide) { this.decide = decide; } public String getMeetContent() { return meetContent; } public void setMeetContent(String meetContent) { this.meetContent = meetContent; } } |
备忘录模式测试程序的代码清单04如下:
程序代码清单04
public class Client { public static void main(String[] args) { Meeting meet1 = new Meeting(); meet1.setMeetName("meetName1"); meet1.setMeetType("meetType1"); meet1.setMeetdate("2009-01-01"); meet1.setMeetLeader("meetLeader1"); meet1.setMeetParticipants("meetParticipants1"); meet1.setDecide("decide1"); meet1.doDecide(); Memento memento = meet1.createMemento(); Caretaker caretaker = new Caretaker(); caretaker.saveMemento(memento.getMeetdate(), memento); Meeting meet2 = new Meeting(); meet2.setMeetName("meetName2"); meet2.setMeetType("meetType2"); meet2.setMeetdate("2009-02-01"); meet2.setMeetLeader("meetLeader2"); meet2.setMeetParticipants("meetParticipants2"); meet2.setDecide("decide2"); meet2.doDecide(); memento = meet2.createMemento(); caretaker.saveMemento(memento.getMeetdate(), memento); caretaker.showContent(); } } |
备忘录模式测试类输出结果如下所示:
显示全部的会议情况: 2009-01-01;会议名称:meetName1;会议类型:meetType1;会议时间:2009-01-01;会议主持人:meetLeader1;会议参加者:meetParticipants1 会议内容:meetParticipants1; 2009-02-01;会议名称:meetName2;会议类型:meetType2;会议时间:2009-02-01;会议主持人:meetLeader2;会议参加者:meetParticipants2 会议内容:meetParticipants2; |
参考链接
11种行为型模式:
Gof23种设计模式(13)——解释器模式(Interpreter)
Gof23种设计模式(14)——模板方法模式(Template Method)
Gof23种设计模式(15)——责任链模式(Chain of Responsibility)
Gof23种设计模式(16)——命令模式(Command)
Gof23种设计模式(17)——迭代器模式(Iterator)
Gof23种设计模式(18)——中介者模式(Mediator)
Gof23种设计模式(19)——备忘录模式(Memento)
Gof23种设计模式(20)——观察者模式(Observer)
Gof23种设计模式(21)——状态模式(State)
Gof23种设计模式(22)——策略模式(Strategy)
Gof23种设计模式(23)——访问者模式(Visitor)
Gof23种设计模式 —— 行为型模式总结和比较
回到总目录:Gof23种设计模式(全解析)
(转载自微信公众号:架构设计模式)