设计模式(18)--Memento(备忘录模式)--行为型
作者QQ:1095737364 QQ群:123300273 欢迎加入!
1.模式定义:
2.模式特点:
3.使用场景:
4.模式实现:

(1)备忘录(Memento)角色
(2)发起人(Originator)角色
(3)负责人(Caretaker)角色
“白箱”备忘录模式的实现

[1]发起人角色类,发起人角色利用一个新创建的备忘录对象将自己的内部状态存储起来。
public class Originator {
private String state;
/**
* 工厂方法,返回一个新的备忘录对象
*/
public Memento createMemento(){
return new Memento(state);
}
/**
* 将发起人恢复到备忘录对象所记载的状态
*/
public void restoreMemento(Memento memento){
this.state = memento.getState();
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
System.out.println("当前状态:" + this.state);
}
}
[2]备忘录角色类,备忘录对象将发起人对象传入的状态存储起来。
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;
}
}
[3]负责人角色类,负责人角色负责保存备忘录对象,但是从不修改(甚至不查看)备忘录对象的内容。
public class Caretaker {
private Memento memento;
/**
* 备忘录的取值方法
*/
public Memento retrieveMemento(){
return this.memento;
}
/**
* 备忘录的赋值方法
*/
public void saveMemento(Memento memento){
this.memento = memento;
}
}
[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");
//恢复发起人对象的状态
o.restoreMemento(c.retrieveMemento());
System.out.println(o.getState());
}
}


“黑箱”备忘录模式的实现

[1]发起人角色类Originator中定义了一个内部的Memento类。由于此Memento类的全部接口都是私有的,因此只有它自己和发起人类可以调用。
package memento.sample2;
/**
* @author chen_dz
* @date :2012-6-2 上午10:11:08
*/
public class Originator { private String state; public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
System.out.println("赋值状态:" + state);
}
/**
* 工厂方法,返还一个新的备忘录对象
*/
public MementoIF createMemento(){
return new Memento(state);
}
/**
* 发起人恢复到备忘录对象记录的状态
*/
public void restoreMemento(MementoIF memento){
this.setState(((Memento)memento).getState());
} private class Memento implements MementoIF{ private String state;
/**
* 构造方法
*/
private Memento(String state){
this.state = state;
} private String getState() {
return state;
}
private void setState(String state) {
this.state = state;
}
}
}
[2]窄接口MementoIF,这是一个标识接口,因此它没有定义出任何的方法。
public interface MementoIF {}
[3]负责人角色类Caretaker能够得到的备忘录对象是以MementoIF为接口的,由于这个接口仅仅是一个标识接口,因此负责人角色不可能改变这个备忘录对象的内容。
public class Caretaker {
private MementoIF memento;
/**
* 备忘录取值方法
*/
public MementoIF retrieveMemento(){
return memento;
}
/**
* 备忘录赋值方法
*/
public void saveMemento(MementoIF memento){
this.memento = memento;
}
}
[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");
//恢复发起人对象的状态
o.restoreMemento(c.retrieveMemento());
}
}
多重检查点

[1]发起人角色源代码
public class Originator {
private List<String> states;
//检查点指数
private int index;
/**
* 构造函数
*/
public Originator(){
states = new ArrayList<String>();
index = 0;
}
/**
* 工厂方法,返还一个新的备忘录对象
*/
public Memento createMemento(){
return new Memento(states , index);
}
/**
* 将发起人恢复到备忘录对象记录的状态上
*/
public void restoreMemento(Memento memento){
states = memento.getStates();
index = memento.getIndex();
}
/**
* 状态的赋值方法
*/
public void setState(String state){
states.add(state);
index++;
}
/**
* 辅助方法,打印所有状态
*/
public void printStates(){
for(String state : states){
System.out.println(state);
}
}
}
[2]备忘录角色类,这个实现可以存储任意多的状态,外界可以使用检查点指数index来取出检查点上的状态。
public class Memento {
private List<String> states;
private int index;
/**
* 构造函数
*/
public Memento(List<String> states , int index){
this.states = new ArrayList<String>(states);
this.index = index;
}
public List<String> getStates() {
return states;
}
public int getIndex() {
return index;
}
}
[3]负责人角色类
public class Caretaker {
private Originator o;
private List<Memento> mementos = new ArrayList<Memento>();
private int current;
/**
* 构造函数
*/
public Caretaker(Originator o){
this.o = o;
current = 0;
}
/**
* 创建一个新的检查点
*/
public int createMemento(){
Memento memento = o.createMemento();
mementos.add(memento);
return current++;
}
/**
* 将发起人恢复到某个检查点
*/
public void restoreMemento(int index){
Memento memento = mementos.get(index);
o.restoreMemento(memento);
}
/**
* 将某个检查点删除
*/
public void removeMemento(int index){
mementos.remove(index);
}
}
[4]客户端角色源代码
public class Client {
public static void main(String[] args) {
Originator o = new Originator();
Caretaker c = new Caretaker(o);
//改变状态
o.setState("state 0");
//建立一个检查点
c.createMemento();
//改变状态
o.setState("state 1");
//建立一个检查点
c.createMemento();
//改变状态
o.setState("state 2");
//建立一个检查点
c.createMemento();
//改变状态
o.setState("state 3");
//建立一个检查点
c.createMemento();
//打印出所有检查点
o.printStates();
System.out.println("-----------------恢复检查点-----------------");
//恢复到第二个检查点
c.restoreMemento(2);
//打印出所有检查点
o.printStates();
}
}



“自述历史”模式

[1]窄接口MementoIF,这是一个标识接口,因此它没有定义出任何的方法。
public interface MementoIF {}
[2]发起人角色同时还兼任负责人角色,也就是说它自己负责保持自己的备忘录对象。
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 m = (Memento)memento;
changeState(m.state);
}
private class Memento implements MementoIF{
private String state;
/**
* 构造方法
*/
private Memento(Originator o){
this.state = o.state;
}
private String getState() {
return state;
}
}
}
[3]客户端角色类
public class Client {
public static void main(String[] args) {
Originator o = new Originator();
//修改状态
o.changeState("state 0");
//创建备忘录
MementoIF memento = o.createMemento();
//修改状态
o.changeState("state 1");
//按照备忘录恢复对象的状态
o.restoreMemento(memento);
}
}
5.优缺点:
(1)备忘录模式的优点
(2)备忘录模式的缺点
6.注意事项
设计模式(18)--Memento(备忘录模式)--行为型的更多相关文章
- 设计模式20:Memento 备忘录模式(行为型模式)
Memento 备忘录模式(行为型模式) 对象状态的回溯 对象状态的变化无端,如何回溯.恢复对象在某个点的状态? 动机(Motivation) 在软件构建过程中,某些对象的状态在转换过程中,可能由于某 ...
- 第18章 备忘录模式(Memento Pattern)
原文 第18章 备忘录模式(Memento Pattern) 备忘录模式 概述: 备忘录模式(Memento Pattern)又叫做快照模式(Snapshot Pattern)或Toke ...
- 重学 Java 设计模式:实战备忘录模式「模拟互联网系统上线过程中,配置文件回滚场景」
作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 实现不了是研发的借口? 实现不了,有时候是功能复杂度较高难以实 ...
- 设计模式学习之备忘录模式(Memento,行为型模式)(19)
假如我们已经记录一个人的个人信息,但是发现信息写错了,然后我先备份下再去修改,结果发现原来的信息是正确的,于是我就看备份的个人信息还原到初始的状态,下面我们用代码去实现 class Program { ...
- 18、Memento 备忘录模式
例如:用于记录快照(顺势状态).存盘 1.Memento Memento设计模式是一种软件设计模式,用于将对象回滚到其先前状态.它是行为设计模式的一部分,与算法和对象之间的职责分配有关. 行为模式描述 ...
- C#设计模式系列:备忘录模式(Memento)
1.备忘录模式简介 1.1>.定义 备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可以将该对象恢复到原先保存的状态. 1.2>.使用频率 ...
- C++设计模式-Memento备忘录模式
Memento模式作用:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态. UML图: Originator:负责创建一个备忘录Me ...
- 《JAVA设计模式》之备忘录模式(Memento)
在阎宏博士的<JAVA与模式>一书中开头是这样描述备忘录(Memento)模式的: 备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式. 备忘录 ...
- java设计模式-----21、备忘录模式
概念: Memento模式也叫备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是GoF的23种设计模式之一,属于行为模式,它的作用是保存对象的内部状态,并在需要的时候(u ...
随机推荐
- C#6.0语言规范(七) 表达式
表达式是运算符和操作数的序列.本章定义了操作数和运算符的语法,求值顺序以及表达式的含义. 表达式分类 表达式分类为以下之一: 一个值.每个值都有一个关联的类型. 一个变量.每个变量都有一个关联的类型, ...
- CentOS7安装MYSQL。
参考这个文章(网页已存到本地):http://www.cnblogs.com/starof/p/4680083.html 安装完成后,本地登录MYSQL没有问题. 现在主要是在windows下用ora ...
- js的相关函数封装(正则表达式,获取url参数,时间格式化)
一:// 验证中文名称 function isChinaName(name) { var pattern = /^[\u4E00-\u9FA5]{1,6}$/ return pattern.test( ...
- Win10 安装 digits
安装caffe配置python接口 接下来就按照官方教程来安装了... 1. If the installation process complains compiler not found, you ...
- POJ 2661
#include<iostream> #include<stdio.h> using namespace std; int main() { //freopen("a ...
- Django模版语言自定义标签-实现前端 关联组合过滤查询
前端关联 组合过滤查询 实现效果如图: models.py 创建表代码 from django.db import models # Create your models here. class Le ...
- expr命令总结
expr在linux中是一个功能非常强大的命令.通过学习做一个小小的总结.1.计算字符串的长度.我们可以用awk中的length(s)进行计算.我们也可以用echo中的echo ${#string}进 ...
- c++处理类型与自定义数据结构
1.typedef 类型别名 有时我们在阅读c++程序时,发现一些未见过的类型,这实际上就是typedef导致的,使用很简单,如下: typedef int wayne; wayne a = , b ...
- TFS2018环境搭建一单实例安装(适用于小型团队)
1.服务器配置 阿里云 单核CPU,2GB的RAM,SSD硬盘,安装TFS实例 TFS2018要求SQL Server 2016 (minimum SP1)以上.其要求有以下几点: (1).安装SQL ...
- Visual Studio最好用的快捷键(你最喜欢哪个)
每次在网上搜关于VS有哪些常用快捷键的时候,出来的永远是一串长的不能再长的列表,完全没体现出“常用”二字,每次看完前面几个就看不下去了,相信大家都 有这种感觉.其实我们平时用的真的只有很少的一部分,借 ...