设计模式学习笔记--备忘录(Mamento)模式
写在模式学习之前
什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方式,这就是软件模式;每个模式描写叙述了一个在我们程序设计中常常发生的问题,以及该问题的解决方式;当我们碰到模式所描写叙述的问题,就能够直接用对应的解决方法去解决问题,这就是设计模式。
设计模式就是抽象出来的东西。它不是学出来的,是用出来的;也许你根本不知道不论什么模式。不考虑不论什么模式。却写着最棒的代码,即使以“模式专家”的角度来看,都是最佳的设计。不得不说是“最佳的模式实践”。这是由于你积累了非常多的实践经验,知道“在什么场合代码应该怎么写”,这本身就是设计模式。
有人说:“水平没到,学也白学,水平到了,无师自通”。
诚然,模式背熟,依旧可能写不出好代码。更别说设计出好框架。OOP理解及实践经验到达一定水平。同一时候也意味着总结了非常多好的设计经验。但"无师自通",却也未必尽然。或者能够说,恰恰是在水平和经验的基础上,到了该系统的学习一下“模式”的时候了。学习一下专家总结的结果。印证一下自己的不足,对于提高水平还是非常有帮助的。
本系列的设计模式学习笔记,实际是对于《Java与模式》这本书的学习记录。
备忘录模式的定义
备忘录模式(Memento Pattern),又叫快照模式(Snapshot Pattern)或Token模式,是对象的行为模式。
备忘录对象是一个用来存储还有一个对象内部状态的快照的对象。
备忘录模式的用意,是在不破坏封装(enscapsolution)的条件下。将还有一个对象的状态捕捉(capture)住,并外部(Externalize)化。存储起来,从来能够在将来合适的时候,把这个对象还原到存储起来的状态。
备忘录模式的结构
结构图
所涉及的角色
(1)备忘录(Memento)角色:将发起人(Originator)角色的内部状态存储起来,能够保护其状态不被发起人对象之外的不论什么对象读取。
(2)发起人(Originator)角色:创建一个含有当前内部状态的备忘录对象,使用备忘录对象存储其内部状态;
(3)负责人(Caretaker)角色:负责保存备忘录对象。不检查备忘录对象的内容。
从以上的职责能够看出。负载人(Caretaker)角色,不过把备忘录(Memento)角色存储起来。功能微小而单一,所以非常多时候,其功能也被集成到发起人(Originator)角色中。形成一种备忘录模式的变种,“自述历史”模式,这可能是备忘录模式的最流行的实现了。
记住这些模式的名字可真是麻烦,非常多时候,我们可能已经在须要快照的编程场景中使用过这样的模式了,但是。真的不知道是备忘录模式。是“自述历史”
代码实现
public class MementoTest {
public static void main(String[] args)
{
Originator o = new Originator();
Caretaker c = new Caretaker(); o.setState("On"); //更改发起人状态为On
System.out.println("Current State : " + o.getState());
c.setMemento(o.createMemento()); //存储快照
o.setState("Off"); //更改发起人状态为Off
System.out.println("Current State : " + o.getState());
o.restoreMemento(c.getMemento()); //从快照恢复状态
System.out.println("Current State : " + o.getState());
}
} 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;
}
}
class Originator
{
private String state;
/**
* 工厂方法,返回一个新的备忘录对象
*/
public Memento createMemento()
{
return new Memento(state);
}
/**
* 将发起人对象恢复到备忘录对象所记录的状态
*/
public void restoreMemento(Memento m)
{
this.state = m.getState();
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
class Caretaker{
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
备忘录模式的优缺点
长处:
(1)有时一些发起人对象的状态信息必须保存在发起人对象以外的地方。可是必须由发起人对象自己读取。
这时备忘录能够把发起人对象内部信息对其它对象屏蔽起来,从而能够恰当的保持封装的边界。
长处&缺点:
这个模式,简化了发起人(Originator)类;当然同一时候添加了备忘录(Memento)类和负责人(Caretaker)类。这算长处还是缺点呢?
仅仅能是我们依据详细的场景。依据实际情况进行选择。
备忘录模式的适用场景
(1)对无状态Http协议的支持技术。比方session、cookie;
(2)一些视窗软件的配置文件。关闭时保存状态,重新启动打开时自己主动到达关闭时的状态。
设计模式学习笔记--备忘录(Mamento)模式的更多相关文章
- 设计模式学习笔记-Adapter模式
Adapter模式,就是适配器模式,使两个原本没有关联的类结合一起使用. 平时我们会经常碰到这样的情况,有了两个现成的类,它们之间没有什么联系,但是我们现在既想用其中一个类的方法,同时也想用另外一个类 ...
- Java-马士兵设计模式学习笔记-装饰者模式
Java装饰者模式简介 一.假设有一个Worker接口,它有一个doSomething方法,Plumber和Carpenter都实现了Worker接口,代码及关系如下: 1.Worker.java p ...
- 研磨设计模式学习笔记2--外观模式Facade
需求:客户端需要按照需求,执行一个操作,操作包括一个系统中的3个模块(根据配置选择是否全部执行). 外观模式优点: 客户端无需知道系统内部实现,,只需要写好配置文件,控制那些模块执行,简单易用. 外观 ...
- 设计模式学习笔记 1.factory 模式
Factory 模式 用户不关心工厂的具体类型,只知道这是一个工厂就行. 通过工厂的实现推迟到子类里面去来确定工厂的具体类型. 工厂的具体类型来确定生产的具体产品. 同时用户不关心这是一个什么样子的产 ...
- 设计模式学习笔记——Composite 组合模式
用于描述无限层级的复杂对象,类似于描述资源管理器,抽象出每一个层级的共同特点(文件夹和文件,展开事件) 以前描述一个对象,是将整个对象的全部数据都描述清楚,而组合模式通过在对象中定义自己,描述自己的下 ...
- 设计模式学习笔记——Bridge 桥接模式
先说一下我以前对桥接模式的理解:当每个类中都使用到了同样的属性或方法时,应该将他们单独抽象出来,变成这些类的属性和方法(避免重复造轮子),当时的感觉是和三层模型中的model有点单相似,也就是让mod ...
- 设计模式学习笔记——Visitor 访问者模式
1.定义IVisitor接口,确定变化所涉及的方法 2.封装变化类.实现IVisitor接口 3.在实体类的变化方法中传入IVisitor接口,由接口确定使用哪一种变化来实现(封装变化) 4.在使用时 ...
- Java-马士兵设计模式学习笔记-责任链模式-FilterChain功能
一.目标 增加filterchain功能 二.代码 1.Filter.java public interface Filter { public String doFilter(String str) ...
- Java-马士兵设计模式学习笔记-责任链模式-处理数据
一.目标 数据提交前做各种处理 二.代码 1.MsgProcessor.java public class MsgProcessor { private List<Filter> filt ...
随机推荐
- 团队开发中git分支的使用
1.Github上保持两个分支:master和develop. master是主分支,对项目进行tag或发布版本等操作,都必须在该分支上进行.最好设为不可提交只能合并的. develop是开发分支,从 ...
- (三)mysql数据库基本操作
(1)SQL语句:结构化查询语句 DDL语句 数据定义语言:数据库丶表丶视图丶索引丶存储过程丶函数丶create drop alter DML语句 数据库操作语言:插入数据insert,删除数据del ...
- python实用技巧 : Filtering os.walk(转)
''' Created on Mar 7, 2010 @author: Diego 需求: 得到某个目录下, 符合过滤条件的文件夹/文件.实现: 将os.walk再次包装. TODO: 不知道本程序的 ...
- python 连接ubuntu xampp mysql
>>> import MySQLdb >>> db=MySQLdb.connect(user="root",passwd="" ...
- [centos6.5]添加eclipse快捷方式
[Desktop Entry] Version=buzhidao Encoding=UTF-8 Name=eclipse Comment=eclipse-for-php Exec=/opt/eclip ...
- ZCMU Problem H: Crixalis's Equipment(贪心,排序)
#include<stdio.h> #include<stdlib.h> struct node { int a,b; }c[1002]; int cmpxy(const st ...
- 洛谷——P1589 泥泞路
P1589 泥泞路 题目描述 暴雨过后,FJ的农场到镇上的公路上有一些泥泞路,他有若干块长度为L的木板可以铺在这些泥泞路上,问他至少需要多少块木板,才能把所有的泥泞路覆盖住. 输入输出格式 输入格式: ...
- yum保留安装包方法,以及存放路径
修改/etc/yum.conf里面的参数keepcache,从0改为1. 安装包保存在/var/cache/yum文件夹下
- 7、Django实战第7天:用form实现登录
Django提供了form对表单进行验证,比如今天要完成的限定登录的时候用户名和密码不能为空,通过这个操作,数据进入到数据库查询之前,我们就可以过滤很多错误,避免不必要的查询. 在users目录下新建 ...
- Linux Shell 量的自增
Linux Shell 中写循环时,常常要用到变量的自增,现在总结一下整型变量自增的方法.我所知道的,bash中,目前有五种方法:1. i=`expr $i + 1`;2. let i+=1;3. ( ...