Java 设计模式系列(十八)备忘录模式(Memento)

备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式。备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。

一、备忘录模式的结构

备忘录模式所涉及的角色有三个:备忘录(Memento)角色、发起人(Originator)角色、负责人(Caretaker)角色。

  • 备忘录(Memento)角色

  (1)将发起人(Originator)对象的内战状态存储起来。备忘录可以根据发起人对象的判断来决定存储多少发起人(Originator)对象的内部状态。

  (2)备忘录可以保护其内容不被发起人(Originator)对象之外的任何对象所读取。

  备忘录有两个等效的接口:

* 窄接口:负责人(Caretaker)对象(和其他除发起人对象之外的任何对象)看到的是备忘录的窄接口(narrow interface),这个窄接口只允许它把备忘录对象传给其他的对象。

  * 宽接口:与负责人对象看到的窄接口相反的是,发起人对象可以看到一个宽接口(wide interface),这个宽接口允许它读取所有的数据,以便根据这些数据恢复这个发起人对象的内部状态。

  • 发起人(Originator)角色:

  (1)创建一个含有当前的内部状态的备忘录对象。

  (2)使用备忘录对象存储其内部状态。

  • 负责人(Caretaker)角色

  (1)负责保存备忘录对象。

  (2)不检查备忘录对象的内容。

源代码

(1) Memento 接口

/**
* 备忘录的窄接口,没有任何方法定义
*/
public interface Memento { }

(2) Originator

/**
* 原发器对象
*/
public class Originator implements Memento {
/**
* 示意,表示原发器的状态
*/
private String state = ""; /**
* 创建保存原发器对象的状态的备忘录对象
* @return 创建好的备忘录对象
*/
public Memento createMemento() {
return new MementoImpl(state);
} /**
* 重新设置原发器对象的状态,让其回到备忘录对象记录的状态
* @param memento 记录有原发器状态的备忘录对象
*/
public void retriveMemento(Memento memento) {
MementoImpl mementoImpl = (MementoImpl)memento;
this.state = mementoImpl.getState();
} /**
* 真正的备忘录对象,实现备忘录窄接口
* 实现成私有的内部类,不让外部访问
*/
private static class MementoImpl implements Memento{
/**
* 示意,表示需要保存的状态
*/
private String state = "";
public MementoImpl(String state){
this.state = state;
}
public String getState() {
return state;
}
}
}

(3) Caretaker

/**
* 负责保存备忘录的对象
*/
public class Caretaker {
/**
* 记录被保存的备忘录对象
*/
private Memento memento = null;
/**
* 保存备忘录对象
* @param memento 被保存的备忘录对象
*/
public void saveMemento(Memento memento){
this.memento = memento;
}
/**
* 获取被保存的备忘录对象
* @return 被保存的备忘录对象
*/
public Memento retriveMemento(){
return this.memento;
}
}

(4) 测试

public class Main {

    public static void main(String[] args) {

        Originator o = new Originator();
Caretaker c = new Caretaker();
//改变负责人对象的状态
o.setState("On");
//创建备忘录对象,并将发起人对象的状态储存起来
c.saveMemento(o.createMemento());
//修改发起人的状态
o.setState("Off");
//恢复发起人对象的状态
o.restoreMemento(c.retrieveMemento()); System.out.println(o.getState());
}
}

二、多备份点

(1) Memento

public interface Memento {
int getIndex();
}

(2) Originator

public class Originator implements Memento {

    //检查点指数
private int index; /** 示意,表示原发器的状态 */
private String state = ""; /** 创建保存原发器对象的状态的备忘录对象 */
public Memento createMemento() {
return new MementoImpl(state, index);
} /** 重新设置原发器对象的状态,让其回到备忘录对象记录的状态 */
public void restoreMemento(Memento memento) {
MementoImpl mementoImpl = (MementoImpl)memento;
this.state = mementoImpl.getState();
index = memento.getIndex();
} // Ingore getter/setter /**
* 真正的备忘录对象,实现备忘录窄接口
* 实现成私有的内部类,不让外部访问
*/
private static class MementoImpl implements Memento {
private int index; /** 示意,表示需要保存的状态*/
private String state = "";
public MementoImpl(String state, int index){
this.state = state;
this.index = index;
} // Ingore getter/setter
}
}

(3) Caretaker

public class Caretaker {
/** 记录被保存的备忘录对象 */
private List<Memento> mementos = new ArrayList<>();
private int current; /** 保存备忘录对象 */
public int saveMemento(Memento memento){
this.mementos.add(memento);
return current++;
} /** 获取被保存的备忘录对象 */
public Memento retrieveMemento(int index){
return this.mementos.get(index);
}
}

(4) 测试

public class Client {

    public static void main(String[] args) {

        Originator o = new Originator();
Caretaker c = new Caretaker();
//改变负责人对象的状态
o.setState("On");
//创建备忘录对象,并将发起人对象的状态储存起来
c.saveMemento(o.createMemento());
//修改发起人的状态
o.setState("Off");
c.saveMemento(o.createMemento());
//恢复发起人对象的状态
o.restoreMemento(c.retrieveMemento(1)); System.out.println(o.getState());
}
}

每天用心记录一点点。内容也许不重要,但习惯很重要!

Java 设计模式系列(十八)备忘录模式(Memento)的更多相关文章

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

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

  2. Java设计模式(十) 备忘录模式 状态模式

    (十九)备忘录模式 备忘录模式目的是保存一个对象的某个状态,在适当的时候恢复这个对象. class Memento{ private String value; public Memento(Stri ...

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

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

  4. Java 设计模式系列(八)装饰者模式

    Java 设计模式系列(八)装饰者模式 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案.Decorator 或 Wrapper 一.装饰模 ...

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

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

  6. Head First 设计模式系列之二----备忘录模式(java版)

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

  7. C#设计模式之十八状态模式(State Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第六个模式,该模式是[状态模式],英文名称是:State Pattern.无论是现实世界,还是面向对象的OO世界,里面都有一个东西,那就是对象.有对象当然就 ...

  8. Java设计模式系列之动态代理模式(转载)

    代理设计模式 定义:为其他对象提供一种代理以控制对这个对象的访问. 动态代理使用 java动态代理机制以巧妙的方式实现了代理模式的设计理念. 代理模式示例代码 public interface Sub ...

  9. Java设计模式系列之责任链模式

    责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道 ...

  10. Java设计模式系列3--抽象工厂模式(Abstract Factory Method)

    2014-02-26 10:55:47 声明:本文不仅是本人自己的成果,有些东西取自网上各位大神的思想,虽不能一一列出,但在此一并感谢! 工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果 ...

随机推荐

  1. 【C#】App_LocalResources实现多语言

    介绍 如果您创建的网页将由使用不同语言的用户阅读,则必须为这些读者提供用他们自己的语言查看网页的方法.一种方法是分别用各语言重新创建页面,但这种方法可能需要大量工作量.容易出错并且在更改原始页时很难维 ...

  2. StreamSets 部署 Pipelines 到 SDC Edge

    可以使用如下方法: 下载edge 运行包并包含pipeline定义文件. 直接发布到edge 设备. 在data colelctor 机器配置并配置了edge server 地址(主要需要网络可访问) ...

  3. Django 思维导图

  4. curl查询公网出口IP

    liuzhizhi@lzz-rmbp|logs # curl ipinfo.io { "ip": "114.110.1.38", "hostname& ...

  5. zipkin:HttpClient和struts

    因为要和老系统集成zipkin,意外的发现老系统使用的httpClient来发送信息.zipkin的官方demo可都是retstTemplate啊!有的搞头. 在看Demo的时候意外的发现其实其实2. ...

  6. laravel 整合 swoole ,并简单 ab 测试对比性能以及在 PHPstorm 中利用debug调试配置swoole服务中的PHP代码

    安装PHP 的 swoole 扩展 及 安装 laravel,就不描述了 整合 laravel 和 swoole 用了这个轮子,侵入性很小,一行代码搞定,推荐一下,今天刚用,不能预测未来是否会遇见坑 ...

  7. C#综合揭秘——细说事务

    引言 其实事务在数据层.服务层.业务逻辑层多处地方都会使用到,在本篇文章将会为大家一一细说. 其中前面四节是事务的基础,后面的三节是事务的重点,对事务有基础的朋友可以跳过前面四节. 文章有错漏的地方欢 ...

  8. flexible.js框架改写

    前一阶段拜读了阿里团队的flexible.js,但是flexible的封装感觉还是不完美,因为flexible还是要依赖less/sass之类的编译执行,所以就存了一些问题,我把这些问题进行整理. 优 ...

  9. PG覆盖率检查

    覆盖率检查 需要gcov和lcov工具,gcov在gcc中自带,lcov需要自行下载安装 重新编译 ./configure --prefix=`pwd`/install --with-perl --w ...

  10. django之模型

    ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...