详解备忘录模式及其在Java设计模式编程中的实现
作者:匆忙拥挤repeat 发布时间:2023-08-24 22:34:02
1. 定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
2. 使用的原因
想要恢复对象某时的原有状态。
3. 适用的情况举例
有很多备忘录模式的应用,只是我们已经见过,却没细想这是备忘录模式的使用罢了,略略举几例:
eg1. 备忘录在jsp+javabean的使用:
在一系统中新增帐户时,在表单中需要填写用户名、密码、联系电话、地址等信息,如果有些字段没有填写或填写错误,当用户点击“提交”按钮时,需要在新增页面上保存用户输入的选项,并提示出错的选项。这就是利用JavaBean的scope="request"或scope="session"特性实现的,即是用备忘录模式实现的。
eg2. 修理汽车的刹车时。首先移开两边的挡板,露出左右刹车片。只能卸下一片,这时另一片作为一个备忘录来表明刹车是怎样安装的。在这片修理完成后,才可以卸下另一片。当第二片卸下时,第一片就成了备忘录。
eg3. 都说人生没有后悔药可买,我们都在为所做的事付出着代价,但在软世界里却有“后悔药”,我改变了某东西的某些状态之后,只要我们之前保存了该东西的某状态,我们就可以通过备忘录模式实现该东西的状态还原,其实这何尝不是一个能使时光倒流的“月光宝盒”,总“神奇”一词了得。
4. 类图结构及说明
(1)类图如下所示:
(2)类说明
(i)Memento:备忘录角色, 主要负责的工作如下:
将发起人对象的内部状态存储起来;
可以保护其内容不被发起人(Originator)对象之外的任何对象所读取。
(ii)Originator:发起人角色,主要完成如下工作:
创建一个含有当前的内部状态的备忘录对象;
使用备忘录对象存储其内部状态。
(iii)Caretaker:负责人角色,完成工作如下:
负责保存备忘录对象;
不保存备忘录对象的内容。
5.实例
/**
* 数据对象
*/
public class DataState {
private String action;
public void setAction(String action) {
this.action = action;
}
public String getAction() {
return action;
}
}
/**
* 一个保存另外一个对象内部状态拷贝 的对象.这样以后就可以将该对象恢复到原先保存的状态.
*/
import java.io.File;
import java.io.Serializable;
public class Memento implements Serializable {
/*private int number;
private File file = null;
public Memento(Originator o) {
this.number = o.getNumber();
this.file = o.getFile();
}
public int getNumber() {
return this.number;
}
public void setNumber(int number) {
this.number = number;
}
public File getFile() {
return this.file;
}
public void setFile(File file) {
this.file = file;
}
*/
private DataState state;
public Memento(Originator o) {
this.state = o.getState();
}
public DataState getState() {
return state;
}
public void setState(DataState state) {
this.state = state;
}
}
public class Originator {
/* private int number;
private File file = null;
public Originator() {
}
// 创建一个Memento,将自身作为参数传入
public Memento getMemento() {
return new Memento(this);
}
// 从Memento中取出保存的数据,恢复为原始状态
public void setMemento(Memento m) {
number = m.getNumber();
file = m.getFile();
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}*/
private DataState state;
public Originator() {
}
public Originator(DataState state) {
this.state = state;
}
// 创建一个Memento,将自身作为参数传入
public Memento getMemento() {
return new Memento(this);
}
// 从Memento中取出保存的数据,恢复为原始状态
public void setMemento(Memento m) {
/*
* getMemento() 创建的对象,保存在某个容器里,
* 当需要恢复时,将其传入当前方法, 再使用getState(),得出
*/
this.state = m.getState();
}
public DataState getState() {
return state;
}
public void setState(DataState state) {
this.state = state;
}
}
/*
* Originator用于 加载数据, 建立Memento对象,及通过Memento恢复原始数据
*/
public class Test {
public static void main(String[] args) {
// Originator originator = new Originator();
// originator.setNumber(8);
//
// Memento memento = originator.getMemento();
// System.out.println(memento.getNumber());
DataState state = new DataState();
state.setAction("copy a character");
Originator originator = new Originator();
System.out.println("创建原始数据");
originator.setState(state);
System.out.println("创建备忘录对象, 保存原始数据状态");
Memento memento = originator.getMemento();
System.out.println("创建了一个新数据");
originator.setState(new DataState());
System.out.println("创建新数据后:" + originator.getState().getAction());
/*
* memento 需要保存在某地,需要时取出,以恢复它内部所保存的数据
*/
System.out.println("创建新数据后,恢复原数据");
originator.setMemento(memento);
System.out.println(originator.getState().getAction());
}
}
打印:
创建原始数据
创建备忘录对象, 保存原始数据状态
创建了一个新数据
创建新数据后:null
创建新数据后,恢复原数据
copy a character
猜你喜欢
- /** * 实现 * @author dujinyang * */顺序是: OneAcitivity
- Java常用类库Math类Math包含用于执行基本数字运算的方法,例如基本指数,对数,平方根和三角函数一、Field SummaryModi
- 系列文章已完成,目录如下:jdk-logging log4j logback日志系统实现机制原理介绍commons-lo
- 已知两个链表list1和list,2,各自非降序排列,将它们合并成另外一个链表list3,并且依然有序,要求保留所有节点。实现过程中,lis
- 本文介绍Android中的5种数据存储方式。数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是
- 前言多数据源的事务处理是个老生常谈的话题,跨两个数据源的事务管理也算是分布式事务的范畴,在同一个JVM里处理多数据源的事务,比较经典的处理方
- 本文介绍了Flutter 实现下拉刷新上拉加载的示例代码,分享给大家,具体如下:效果图 使用方法添加依赖depende
- 参数和返回值得加密目的为了保证接口不被人拦截下来恶意请求,保证程序的稳定性,我们可以使用接口加密的方法来保证参数和返回值的保密性。具体实现方
- MultiFrameImageStreamCompleterMultiFrameImageStreamCompleter 是一个可组合的 I
- 效果展示在实际项目当中我们经常看到如下各种剪裁形状的效果,Flutter 为我们提供了非常方便的 Widget 很轻松就可以实现,下面我们来
- 前言为什么用动静态库我们在实际开发中,经常要使用别人已经实现好的功能,这是为了开发效率和鲁棒性(健壮性);因为那些功能都是顶尖的工程师已经写
- 1 StringString:字符串常量,字符串长度不可变。2 StringBufferStringBuffer:字符串变量(Synchro
- 1、通过查找API文档:2、Map.Entry是一个接口,所以不能直接实例化。3、Map.entrySet( )返回的是一个collecti
- JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展
- 我们还是用一个小例子来看看自定义View和自定义属性的使用,带大家来自己定义一个带进度的圆形进度条,我们还是先看一下效果吧从上面可以看出,我
- JDK 1.5开始提供ScheduledThreadPoolExecutor类,ScheduledThreadPoolExecutor类继承
- jdk8之前 一、java.lang.Systemlong times = System.currentTimeMillis();
- 在java.lang.Runtime.exec的使用中,我们经常会用到将重定向命令执行的输入/结果或者将错误信息读取出来.那么,在使用过程中
- 本文实例讲述了Java简单验证身份证功能。分享给大家供大家参考,具体如下:package org.cxy.csdn.example;impo
- 光流的概念是由一个叫Gibson的哥们在1950年提出来的。它描述是空间运动物体在观察成像平面上的像素运动的瞬时速度,利用图像序列中像素在时