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

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

    JAVA 1. what is thread safe? 线程安全就是说多线程访问同一代码,不会产生不确定的结果.编写线程安全的代码是低依靠线程同步.线程安全: 在多线程中使用时,不用自已做同步处理线 ...

  2. PAT 1012

    1012. The Best Rank (25) To evaluate the performance of our first year CS majored students, we consi ...

  3. Android 开发中的屏幕适配技术详解

    本文主要介绍Android开发中比较头疼繁琐的一个问题-屏幕适配问题.主要从适配原因.基本核心概念.适配方法等方面介详细 介绍从而是的深入或者进一步对Android屏幕适配技术的掌握和理解. 真题园网 ...

  4. Python基础:1.数据类型(字典)

    提示:python版本:2.7,windows系统 1.字典(Dictionary) 由Key-Value组成,一个Key只能对应一个Value >>> colors = {'red ...

  5. Oracle恢复已删除数据

    Oracle恢复已删除的数据,主要有两种方法:SCN和时间戳. 一.通过SCN恢复删除且已提交的数据 1.获得当前数据库的scn号 select current_scn from v$database ...

  6. 使用开源库PhotoView

    一.下载地址:https://github.com/chrisbanes/PhotoView 点击DownLoad ZIP,进行下载. 二.解压,然后复制PhotoView-master\librar ...

  7. 基于 JQUERY 网页 banner

    demo.html <html> <head> <title>demo</title> <link href="css/PaPaBann ...

  8. 까페24 호스팅 php 에러메세지 출력

    [문제점] 최근 까페24호스팅에서 php작업시화면에 에러메세지가 나오지 않아 디버깅시에 매우 곤란함 [해결책] .htaccess 내용에 아래추가.=================== ...

  9. PHP之数组函数归类

    数组之所以强大,除了本身声明.存储方式灵活,它还有坚强后盾:一系列功能各异的数组处理函数.就像一只军队,除了领队将军本身能征善战,指挥英明之外,还有一群不怕死.忠实于他的士兵,这样才能显得整体的强大. ...

  10. 给你看看我练习的oracle语句

    -------预算-- CREATE OR REPLACE VIEW V_YUSUAN_BGY_WZ20151204 AS SELECT tb_cube_fc05.pk_entity pk_org,/ ...