申明:这几天无意中关注到备忘录模式,比较陌生回家一番参考书,只在附录里记录了该模式。后来在园子里有发现了有专门写设计模式的博客,并且写的也得牛逼。附上链接

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版)的更多相关文章

  1. Java进阶篇设计模式之十二 ---- 备忘录模式和状态模式

    前言 在上一篇中我们学习了行为型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern).本篇则来学习下行为型模式的两个模式,备忘录模式(Memento Pat ...

  2. Java设计模式之十二 ---- 备忘录模式和状态模式

    前言 在上一篇中我们学习了行为型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern).本篇则来学习下行为型模式的两个模式,备忘录模式(Memento Pat ...

  3. Java 设计模式系列(二十)状态模式

    Java 设计模式系列(二十)状态模式 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式.状态模式允许一个对象在其内部状态改变的时候改 ...

  4. Java 设计模式系列(二二)责任链模式

    Java 设计模式系列(二二)责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求 ...

  5. Java设计模式(15)备忘录模式(Memento模式)

    Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public class ...

  6. CDC不同模式在ODI体现系列之二 异步模式

    CDC不同模式在ODI体现系列之二 异步模式 2 异步模式需要在数据库中做一些准备工作: 改数据为归档并启用logminer: SQL> shutdown immediate 数据库已经关闭. ...

  7. 设计模式之第17章-备忘录模式(Java实现)

    设计模式之第17章-备忘录模式(Java实现) 好男人就是我,我就是曾小贤.最近陈赫和张子萱事件闹得那是一个沸沸扬扬.想想曾经每年都有爱情公寓陪伴的我现如今过年没有了爱情公寓总是感觉缺少点什么.不知道 ...

  8. C#设计模式之二十二备忘录模式(Memeto Pattern)【行为型】

    一.引言   今天我们开始讲"行为型"设计模式的第十个模式,该模式是[备忘录模式],英文名称是:Memento Pattern.按老规矩,先从名称上来看看这个模式,个人的最初理解就 ...

  9. C#设计模式之二十二备忘录模式(Memento Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第十个模式,该模式是[备忘录模式],英文名称是:Memento Pattern.按老规矩,先从名称上来看看这个模式,个人的最初理解就是对某个对象的状态进行保 ...

随机推荐

  1. iOS开发-分页栏和选取器的使用

    一.分页栏 创建一个新的项目,Subclass of的值选中UIViewController,然后在storyboard中删除根视图,在右下方拖出一个Tab Bar Controller 新增分页,只 ...

  2. iOS UITabBarItem 选中图的颜色,设置UIimage的渲染模式

    UITbarController之前有在这篇文章讲解:http://www.cnblogs.com/niit-soft-518/p/4447940.html 如果自定义了UITabBarItem的图片 ...

  3. VM使用标准交换机

    1.新建模板: 网卡选择“未连接”,此处看不到“标准交换机”选项

  4. hdu 5461 Largest Point 暴力

    Largest Point Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...

  5. [Bootstap] 9. Dropdown

    Dropdown Arrow Class In order to create a down arrow like this: , what class should we apply to the ...

  6. Storyboards vs NIB vs Code 大辩论

    前言 做iOS开发的童鞋都应该会纠结一个问题,那就是在做开发的时候是使用StoryBoard还是使用Nibs又或者是Code(纯代码流)呢?笔者也非常纠结这个问题,今天碰巧在raywenderlich ...

  7. [转载]GDB十分钟教程

    转自:http://blog.csdn.net/liigo/article/details/582231/ GDB十分钟教程 作者: liigo原文链接: http://blog.csdn.net/l ...

  8. Python 基础【第六篇】字典

    1.字典定义: 字典和列表类似 只是字典标示符用的是字符而列表用的是0开始的数字,字典中每个元素对应一个值 这个元素叫做键(key)键值不能重复 value(值)可以重复 2.字典格式: 格式一: [ ...

  9. [原]Unity3d中奇怪的编译错误

    整理项目,重新build时出现一些问题,这些代码在原项目中都是可以运行的. 错误信息如下: Assets/XXXXX.cs(79,35): error CS0103: The name `NNNNNN ...

  10. gluster 安装配置基本指南

    基于网络上的多篇文章,做了一些调整. gluster安装 ###  Installing Gluster wget -P /etc/yum.repos.d http://download.gluste ...