Head First 设计模式系列之二----备忘录模式(java版)
申明:这几天无意中关注到备忘录模式,比较陌生回家一番参考书,只在附录里记录了该模式。后来在园子里有发现了有专门写设计模式的博客,并且写的也得牛逼。附上链接
http://www.cnblogs.com/java-my-life/tag/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/,真的写的很好。对于这个并不熟悉的模式,我也就参考他写的,并且以后肯定也会大量参考他写的。
在儿时肯定上过游戏室吧,笔者当时西游记很火,我们四个小伙准备了好些钱,打算把游戏给打穿了。死了就接着投牌下去,接着刚才的剧情玩下去,到最后钱完了,四个人还是没有打穿。其实这里就包含着备忘录模式,死了以后记住你当前的状态,钱投下去了,恢复到当前状态接着玩,而不是从第一关苦逼开始。
一、定义和类图
备忘录对象是一人用来存储加外一个对象内部状态的快照对象。备忘录模式的用意是在不破坏封装条件下,将一个对象的状态捕捉信,并且外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常与命令模式和迭代模式一同使用(这个真没试用)。

Originator(发起人角色)、Memento(备忘录角色)、Caretaker(负责人角色)
形象说:土豪把钱装进箱子存进银行
二、代码实现
Originator类
package design.a.memento;
/**
* 发起人角色
* @author team
*
*/
public class Originator {
private String state; //创建备忘录角色
public Memento createMemennto() {
return new Memento(state);
} //恢复到某个备忘录对象记录的角色
public void restoreMemento(Memento memento) {
this.setState(memento.getState());
} public String getState() {
return state;
} public void setState(String state) {
this.state = state;
System.out.println("当前状态:" + this.state);
}
}
Memento类:
package design.a.memento;
/**
* 备忘录角色
*
* @author team
*
*/
public 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;
} }
Caretaker类
package design.a.memento;
/**
* 负责人角色
* @author team
*
*/
public class Caretaker {
private Memento memento; public void saveMemento(Memento memento) {
this.memento = memento;
} public Memento retrieveMemento() {
return this.memento;
} }
MainTest类
package design.a.memento;
public class MainTest {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
//设置初始状态
originator.setState("off");
//创建备忘录对象(已经存了状态),并把这个备忘录对象存起来
caretaker.saveMemento(originator.createMemennto());
//更改状态
originator.setState("on");
//恢复状态
originator.restoreMemento(caretaker.retrieveMemento());
}
}
运行结果:
当前状态:off
当前状态:on
当前状态:off
认真的人会想到这两个问题:1.为什么创建的备忘录对象还要保存到负责人手里。这个负责人其实就是负责管理这个备忘录对象的,假如后面要求说恢得到某个状态,这时就需要这个负责人来统一管理了。(土豪没空保管钱装进箱子,请了个银行帮他保管,而不是放在家里自己管)
2.从上面的代码实现你会发现这个备忘录对象是对发起人和负责人都透明的,这是多么危险啊。(你装进箱子多少钱,让帮你保管钱的人知道了,说不定就会起非心,要是能够让帮你保管钱的人连里面装的是什么那多么好啊,就给他个箱子,你来保管吧)这个在java里面就可以用到接口和内部类来实现。
将Memento设成Originator类的内部类,从而将Memento对象封装在Originator里面;在外部提供一个标识接口MementoIF给Caretaker以及其他对象。

三、代码实现plus
Originator类
package design.a.mementoPlus;
/**
*
* @author team
*
*/
public class Originator {
private String state; public void setState(String state) {
this.state = state;
System.out.println("当前状态:" + this.state);
} public String getState() {
return this.state;
} public MementoIF createMemento() {
return new Memento(state);
} public void restoreMemento(MementoIF memento) {
this.setState(((Memento)memento).getState());
} class Memento implements MementoIF {
private String state; private Memento(String state) {
this.state = state;
}
public String getState() {
return this.state;
} public void setState(String state) {
this.state = state;
}
}
}
MementoIF接口
package design.a.mementoPlus;
/**
*
* @author team
*
*/
public interface MementoIF { }
Caretaker类
package design.a.mementoPlus;
/**
*
* @author team
*
*/
public class Caretaker {
private MementoIF memento;
//备忘录对象获取
public MementoIF retrieveMemento() {
return memento;
}
//备忘录赋值
public void saveMemento(MementoIF memento){
this.memento = memento;
}
}
MainTest类
package design.a.mementoPlus;
/**
*
* @author team
*
*/
public class MainTest {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
//设置初始状态
originator.setState("off");
//创建备忘录对象(已经存了状态),并把这个备忘录对象存起来
caretaker.saveMemento(originator.createMemento());
//更改状态
originator.setState("no");
//恢复状态
originator.restoreMemento(caretaker.retrieveMemento()); }
}
运行结果:
当前状态:off
当前状态:no
当前状态:off
问题来了:就像上面说的问题1负责人哪能就干这么简单的事,(土豪钱多要保存多个箱子,让他随时取出他想要的箱子)我们就需要存储多个状态
备忘录模式可以将发起人对象的状态存储到备忘录对象里面,备忘录模式可以将发起人对象恢复到备忘录对象所存储的某一个检查点上。

四、代码实现plus++
Originator类
package design.a.mementoPlus2;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author team
*
*/
public class Originator {
private List<String> states; public Originator() {
states = new ArrayList<String>();
}
//创建备忘录
public Memento createMemento() {
return new Memento(states);
}
//恢复到备忘录记录的状态
public void restoreMemento(Memento memento) {
states = memento.getStates();
}
//状态赋值
public void setState(String state) {
states.add(state);
}
//打印状态
public void printStates() {
for(String state : states) {
System.out.println(state);
}
}
}
Memento类
package design.a.mementoPlus2;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author team
*
*/
public class Memento {
private List<String> states; public Memento(List<String> states) {
this.states = new ArrayList<String>(states);
} public List<String> getStates() {
return states;
} }
Caretaker类
package design.a.mementoPlus2;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author team
*
*/
public class Caretaker {
private Originator originator; private List<Memento> mementos = new ArrayList<Memento>(); public Caretaker(Originator originator) {
this.originator = originator;
}
//创建备忘录
public void createMemento() {
Memento memento = originator.createMemento();
mementos.add(memento);
}
//恢复到备忘录记录的状态
public void restoreMemento(int index) {
Memento memento = mementos.get(index);
originator.restoreMemento(memento);
} }
MainTest类
package design.a.mementoPlus2;
/**
*
* @author team
*
*/
public class MainTest {
public static void main(String[] args) {
Originator originator = new Originator(); Caretaker caretaker = new Caretaker(originator); originator.setState("state one"); caretaker.createMemento(); originator.setState("state two"); caretaker.createMemento(); originator.setState("state three"); caretaker.createMemento(); originator.setState("state four"); caretaker.createMemento(); System.out.println("打印当前所有状态");
originator.printStates(); caretaker.restoreMemento(2); System.out.println("打印恢复后的所有状态");
originator.printStates(); }
}
注意刚才写Memento备忘录时开始:this.states = states;造成运行一直出错,states是个List是对象引用,所以return new Memento(states);每次产生的Memento
里面的states都是指向同一个的。应该写成this.states = new ArrayList<String>(states);
运行结果
打印当前所有状态
state one
state two
state three
state four
打印恢复后的所有状态
state one
state two
state three
所谓“自述历史”模式(History-On-Self Pattern)实际上就是备忘录模式的一个变种。在备忘录模式中,发起人(Originator)角色、负责人(Caretaker)角色和备忘录 (Memento)角色都是独立的角色。虽然在实现上备忘录类可以成为发起人类的内部成员类,但是备忘录类仍然保持作为一个角色的独立意义。在“自述历 史”模式里面,发起人角色自己兼任负责人角色。

五、代码实现plus++++
MementoIF接口
package design.a.mementoPlus3;
/**
*
* @author team
*
*/
public interface MementoIF { }
Originator类
package design.a.mementoPlus3;
/**
*
* @author team
*
*/
public class Originator {
public String state; public void changeState(String state) {
this.state = state;
System.out.println("状态改为:" + state);
} public Memento createMemento() {
return new Memento(this);
} public void restoreMemento(MementoIF memento) {
Memento memento2 = (Memento) memento;
changeState(memento2.state);
} private class Memento implements MementoIF {
private String state; private Memento(Originator originator) {
this.state = originator.state;
}
}
}
MainTest类
package design.a.mementoPlus3;
public class MainTest {
public static void main(String[] args) {
Originator originator = new Originator();
originator.changeState("state one");
MementoIF memento = originator.createMemento();
originator.changeState("state two");
originator.restoreMemento(memento);
}
}
运行结果:
状态改为:state one
状态改为:state two
状态改为:state one
由于在实际中还没有应用过备忘录模式,后面可能还会再写一篇应用的。
Head First 设计模式系列之二----备忘录模式(java版)的更多相关文章
- Java进阶篇设计模式之十二 ---- 备忘录模式和状态模式
前言 在上一篇中我们学习了行为型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern).本篇则来学习下行为型模式的两个模式,备忘录模式(Memento Pat ...
- Java设计模式之十二 ---- 备忘录模式和状态模式
前言 在上一篇中我们学习了行为型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern).本篇则来学习下行为型模式的两个模式,备忘录模式(Memento Pat ...
- Java 设计模式系列(二十)状态模式
Java 设计模式系列(二十)状态模式 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式.状态模式允许一个对象在其内部状态改变的时候改 ...
- Java 设计模式系列(二二)责任链模式
Java 设计模式系列(二二)责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求 ...
- Java设计模式(15)备忘录模式(Memento模式)
Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public class ...
- CDC不同模式在ODI体现系列之二 异步模式
CDC不同模式在ODI体现系列之二 异步模式 2 异步模式需要在数据库中做一些准备工作: 改数据为归档并启用logminer: SQL> shutdown immediate 数据库已经关闭. ...
- 设计模式之第17章-备忘录模式(Java实现)
设计模式之第17章-备忘录模式(Java实现) 好男人就是我,我就是曾小贤.最近陈赫和张子萱事件闹得那是一个沸沸扬扬.想想曾经每年都有爱情公寓陪伴的我现如今过年没有了爱情公寓总是感觉缺少点什么.不知道 ...
- C#设计模式之二十二备忘录模式(Memeto Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第十个模式,该模式是[备忘录模式],英文名称是:Memento Pattern.按老规矩,先从名称上来看看这个模式,个人的最初理解就 ...
- C#设计模式之二十二备忘录模式(Memento Pattern)【行为型】
一.引言 今天我们开始讲“行为型”设计模式的第十个模式,该模式是[备忘录模式],英文名称是:Memento Pattern.按老规矩,先从名称上来看看这个模式,个人的最初理解就是对某个对象的状态进行保 ...
随机推荐
- Android Studio 编译不通过,报错“找不到org.apache.http
如果你使用的 target sdk是23请在build.gradle加入 android{ useLibrary ‘org.apache.http.legacy‘ }
- listview自定义背景以及item自定义背景
item向自定义背景,可以根据position来设置不同的背景. listview背景设置是需要注意设置下面这几项: //点下时整个页面的背景 android:cacheColorHint=" ...
- android学习日记23--Android XML解析
一.简述 XML语言是跨平台,JAVA对XML语言支持得比较好,android系统的应用层平台是JAVA做的,所以用XML.XML解析比较简单.XML解析就是将获取到的数据分离出来,基本的网络数据传输 ...
- Linux中的文件描述符与打开文件之间的关系------------每天进步一点点系列
http://blog.csdn.net/cywosp/article/details/38965239 1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件. ...
- careercup-中等难度 17.4
17.4 编写一个方法,找出两个数字中最大的那一个.不得使用if-else或其他比较运算符. 解法: 我们可以通过一步步的分析来将需要用到的if-else和比较操作符去掉: If a > b, ...
- USB HID usage table
This usage table lets usbhidctl decode the HID data correctly for the APC RS/XS1000's. This work was ...
- Mysql-5.6乱码问题
1 参考:http://www.testwo.com/blog/6930 mysql数据库默认的编码是:Latin1,要想支持中文需要修改为gbk/utf8的编码格式. 1.以root管理员身份查 ...
- Android_Handler
xml文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...
- 最大公约数与欧几里得(Euclid)算法
---恢复内容开始--- 记a, b的最大公约数为gcd(a, b).显然, gcd(a,b)=gcd(|a|,|b|). 计算最大公约数的Euclid算法基于下面定理: [GCD递归定理]对于任意非 ...
- Nim游戏(组合游戏Combinatorial Games)
http://baike.baidu.com/view/1101962.htm?fr=aladdin Nim游戏是博弈论中最经典的模型(之一),它又有着十分简单的规则和无比优美的结论 Nim游戏是组合 ...