概念:

  Memento模式也叫备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是GoF的23种设计模式之一,属于行为模式,它的作用是保存对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。

  在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

  备忘录模式的结构

  备忘录模式的角色和职责

  1、Originator(原生者):需要被保存状态以便恢复的那个对象,负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。

  2、Memento(备忘录):该对象由Originator创建,主要负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator却可看到备忘录的宽接口,允许它访问返回到先前状

态所需要的所有数据。

  3、Caretaker(管理者):负责在适当的时间保存/恢复Originator对象的状态,负责备忘录Memento,不能对Memento的内容进行访问或者操作。

  备忘录模式的应用场景

  如果一个对象需要保存状态并可通过undo或rollback等操作恢复到以前的状态时,可以使用Memento模式。

  (1)一个类需要保存它的对象的状态(相当于Originator角色)
  (2)设计一个类,该类只是用来保存上述对象的状态(相当于Memento角色)
  (3)需要的时候,Caretaker角色要求Originator返回一个Memento并加以保存
  (4)undo或rollback操作时,通过Caretaker保存的Memento恢复Originator对象的状态

  下面用代码来实现一下

  首先,新建一个Person类,他就是Originator(原生者)

 /*
* Originator(原生者)
*/
public class Person {
/*
* 姓名,年龄,性别就是结构图中的state,状态属性
*/
//姓名
private String name;
//年龄
private int age;
//性别
private String sex; public Person() {
super();
} public Person(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public void display() {
System.out.println("name:" + name + ",sex:" + sex + ",age:" + age);
} //创建一个备份
public Memento createMemento(){
return new Memento(name,age,sex);
} //恢复一个备份
public void setMemento(Memento memento){
this.name = memento.getName();
this.age = memento.getAge();
this.sex = memento.getSex();
}
}

  接着,创建一个Memento(备忘录),他和Originator的基本结构是一样的

 /*
* Memento(备忘录)
*/
public class Memento {
//姓名
private String name;
//年龄
private int age;
//性别
private String sex; public Memento() {
super();
} public Memento(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
}
}

  接下来,创建客户端运行一下

 public class MainClass {
public static void main(String[] args) {
Person person = new Person("小明",18,"男");
//打印
person.display(); //创建一个备份
Memento memento = person.createMemento(); person.setName("小红");
person.setAge(17);
person.setSex("女");
//打印
person.display(); //备份还原
person.setMemento(memento);
//打印
person.display();
}
}

  结果:

  这样,就做到了一个备份还原的过程,但是可以看到,根据结构图看,我们还缺少了一个Caretaker(管理者)角色

  这个角色的作用其实就是把备份还原的过程交到管理者手中,通过管理者来备份还原

 /*
* Caretaker(管理者)
*/
public class Caretaker {
//持有一个对Memento的引用
private Memento memento; public Memento getMemento() {
return memento;
} public void setMemento(Memento memento) {
this.memento = memento;
}
}

  客户端

 public class MainClass {
public static void main(String[] args) {
Person person = new Person("小明",18,"男");
//打印
person.display(); //创建一个管理者
Caretaker caretaker = new Caretaker(); //创建一个备份
// Memento memento = person.createMemento();
caretaker.setMemento(person.createMemento()); person.setName("小红");
person.setAge(17);
person.setSex("女");
//打印
person.display(); //备份还原
person.setMemento(caretaker.getMemento());
//打印
person.display();
}
}

  运行结果是一样的

  备忘录模式的优点和缺点

  一、备忘录模式的优点
    1、有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时,使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
    2、本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。
    3、当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
  二、备忘录模式的缺点:
    1、如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。
    2、当负责人角色将一个备忘录存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。
    3、当发起人角色的状态改变的时候,有可能这个协议无效。如果状态改变的成功率不高的话,不如采取“假如”协议模式。

java设计模式-----21、备忘录模式的更多相关文章

  1. 折腾Java设计模式之备忘录模式

    原文地址:折腾Java设计模式之备忘录模式 备忘录模式 Without violating encapsulation, capture and externalize an object's int ...

  2. java设计模式之备忘录模式

    备忘录模式 备忘录模式是一种软件设计模式:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.一听到备忘录这个字的时候想起了小小时打的游 ...

  3. java设计模式9.备忘录模式、访问者模式、调停者模式

    备忘录模式 备忘录模式又叫快照模式,备忘录对象是一个用来存储另外一个对象内部状态快照的对象.备忘录的用意是在不破坏封装的条件下,将一个对象的状态捕捉,并外部化存储起来,从而可以在将来合适的时候把这个对 ...

  4. Java设计模式应用——备忘录模式

    备忘录模式主要用于存档.游戏中我们打boss前总会存档,如果打boss失败,则读取存档,重新挑战boss. 可以看出来,备忘录模式一般包括如下数据结构 1. 存档文件:用于恢复备份场景的必要数据: 2 ...

  5. 19.java设计模式之备忘录模式

    基本需求 游戏的角色有攻击力和防御力,在大战Boss之前保存自身的状态(攻击力和防御力),当大战Boss之后攻击力和防御力下降,从备忘录对象恢复到大战前的状态 传统方案 一个对象,就对应一个保存对象状 ...

  6. 观世音甘泉活树的故事竟然是Java设计模式:备忘录模式

    目录 定义 意图 主要解决问题 何时使用 优缺点 结构 白箱实现 黑箱实现 多重检查点 观世音甘泉活树的故事 定义 备忘录模式是对象的行为型模式,备忘录对象是一个用来存储另外一个对象内部状态的快照的对 ...

  7. 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)

    原文:乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) 作者:webabc ...

  8. Java设计模式——装饰者模式

    JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...

  9. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

  10. JAVA设计模式--装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...

随机推荐

  1. C/C++掌握技能(一)

    1.在编译器中输入代码并将其保存为.cpp文件(C语言的文件扩展名.c,但为了使用C++中的一些好用的特性,请把文件扩展名改为C++的.cpp)2.等价头文件:#include<stdio.h& ...

  2. 通过修改EIP寄存器实现远程注入

    功能:通过修改EIP寄存器实现32位程序的DLL注入(如果是64位,记得自己对应修改汇编代码部分) 原理: 挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,然后把相关的指令机器码和数据拷贝 ...

  3. 预防和避免死锁的方法及银行家算法的java简单实现

    预防死锁 (1) 摒弃"请求和保持"条件 基本思想:规定所有进程在开始运行之前,要么获得所需的所有资源,要么一个都不分配给它,直到所需资源全部满足才一次性分配给它. 优点:简单.易 ...

  4. Android逆向——smali复杂类解析

    i春秋作家:HAI_ 之前在Android逆向——初识smali与java类中讲解了基本的HelloWorld和简单类.这节课就要进一步深入.如果能够耐下心来分析一定会有所收获.——写给自己和后来人. ...

  5. HDFS概要

    --HDFS-- Hadoop Distributed File System HDFS一个分布式,高容错,可线性扩展的文件系统 简介: Hadoop分布式文件系统(HDFS)是一种分布式文件系统,设 ...

  6. 【xsy2272】 与运算 状压dp

    题目大意:给你一个长度为$n$的序列$a$,我们定义$f_i$表示序列$a$前i项一次进行按位与运算后的值. 我们认为一个序列的价值为$\sum_{i=1}^{n}f_i$,现在你要重新排列序列$a$ ...

  7. 【xsy2506】 bipartite 并查集+线段树

    题目大意:有$n$个点,你需要操作$m$次.每次操作为加入/删除一条边. 问你每次操作后,这$n$个点构成的图是否是二分图. 数据范围:$n,m≤10^5$. 此题并没有强制在线,考虑离线做法. 一条 ...

  8. odoo开发环境搭建(一):安装VMware Workstation

    odoo开发环境搭建(一):安装VMware Workstation

  9. (转)Linux top命令的用法详细详解

    原文:https://yq.aliyun.com/articles/399004?spm=a2c4e.11153940.blogcont399002.9.3a19f00aHOA3SH# 摘要: 首先介 ...

  10. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(八):MyBatis分页功能实现

    使用Mybatis时,最头痛的就是写分页,需要先写一个查询count的select语句,然后再写一个真正分页查询的语句,当查询条件多了之后,会发现真不想花双倍的时间写 count 和 select,幸 ...