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

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. java正则表达式入门基础

    一.正则表达式术语 1)元字符 : 非一般字符,具有某种意义的字符.如 : \bX : \b边界符, 以 X开始的单词 2) 常用 : \d : 匹配一个数字 : \d ,  匹配至少一个以上数字 \ ...

  2. 【转】移动前端手机输入法自带emoji表情字符处理

    http://blog.csdn.net/binjly/article/details/47321043 今天,测试给我提了一个BUG,说移动端输入emoji表情无法提交.很早以前就有思考过,手机输入 ...

  3. Ubuntu下非常给力的下载工具

    Windows下的下载工具--迅雷,之所以下载速度快,乃是它能搜索资源.为己所用,而不是仅仅从原始地址这单一资源处下载. Ubuntu下也有类似的工具,那就是aira2. aira2是一个命令行下载工 ...

  4. 【转】如何从零开始学会 Ruby on Rails?

    文章转自:http://huacnlee.com/blog/how-to-start-learning-ruby-on-rails/ 这个话题曾经给身边的很多朋友说过同样的话题,这里整理以下. 如果你 ...

  5. JS知识点备忘

    做前端久了,会发现很多比较杂的知识点,平时很少用到(往往在面试的时候经常见到),但是遇到的时候会很揪心...所以遇到的时候把它记录下来,但求有个印象,再次遇到时,可以在这里快速找到解决. 1.文档碎片 ...

  6. Hive权限介绍

    一.开启权限 眼下hive支持简单的权限管理,默认情况下是不开启.这样全部的用户都具有同样的权限.同一时候也是超级管理员.也就对hive中的全部表都有查看和修改的权利,这样是不符合一般数据仓库的安全原 ...

  7. Android下实现GPS定位服务

    1.申请Google API Key,参考前面文章 2.实现GPS的功能需要使用模拟器进行经纬度的模拟设置,请参考前一篇文章进行设置 3.创建一个Build Target为Google APIs的项目 ...

  8. 《RESTful Web Services》第一章 使用统一接口

    序言 HTTP是一种应用层协议.SOAP和一些Ajax Web框架都将HTTP作为一种传输信息的协议,难以充分利用HTTP层的基础设施. 1.2 如何保持交互的可见性     可见性是HTTP的一个核 ...

  9. mysql事务问题

    mysql事务: 若mysql 开启事务后START TRANSACTION ,不显示提交commit,则默认自动回滚,而不是默认自动提交.

  10. CCCatmullRomTo&CCCatmullRomBy

    注: 云形线(Catmull-Rom curve曲线) 云线(Spline或B-spline)在数学上有很多种类,常用的三阶云线有Hermite, Bezier, Uniform B-spline, ...