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

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. Css基础-介绍及语法

    css 文件后缀.css 基础语法: selector { property:value } 例如: h1 {color:red;font-size:14px;} color:字体颜色  font-s ...

  2. <meta 标签的详细使用

    meta是用来在HTML文档中模拟HTTP协议的响应头报文.meta 标签用于网页的<head>与</head>中,meta   标签的用处很多.meta  的属性有两种:na ...

  3. windows7下硬盘安装ubuntu14.04

    windows7 ubuntu1404双系统 准备软件 安装步骤 step 1 step 2 step 3 step 4 windows7 + ubuntu14.04双系统 准备软件 1)grub4d ...

  4. CRM-BP相关FUNCTION

    获取BP的地址信息:BUPA_ADDRESS_GET_DETAIL 修改BP的信息:CRM_WAP_BP_CHANGE BUTO50存放2个BP之间的关系 获取BP的角色 BAPI_BUPA_ROLE ...

  5. android学习日记13--数据存储之File存储

    4.文件存储File File即传统的I/O 流存储文件,Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的 ...

  6. Linux下批量改动名字方法

    如果任务是把文件夹下全部的.log后缀文件名称中的2014去掉. 方法一) 脚本 这样的方法通过ls把当前文件夹下全部的文件进行遍历,然后获取文件名称,进行mv操作.例如以下: #!/bin/sh f ...

  7. 转--23种设计模式的搞笑解释(后续放逐一C++解释版本)

    创建型模式 1.FACTORY —追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了.麦当劳和肯德 ...

  8. 20 Best Drag and Drop jQuery Plugins--reference

    reference from:http://dizyne.net/20-best-drag-drop-jquery-plugins/ jQuery has done a great job repla ...

  9. FactoryBean的使用--转

    一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化bean .在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的 ...

  10. WebGoat视频教程下载

    WebGoat视频教程下载:http://pan.baidu.com/s/1pJlsfQ7