Memento模式(备忘录设计模式)
Memento模式?
使用面向对象编程的方式实现撤销功能时,需要事先保存实例的相关状态信息。然后,在撤销时,还需要根据所保存的信息将实例恢复至原来的状态。这个时候你需要使用Memento设计模式。(以及实例实现对状态的保存)
关键字:
1.·Undo(撤销)
2.·Redo(重做)
3.·History(历史记录)
4。·Snapshot(快照)破坏封装性:
将依赖于实例内部结构的代码分散地编写在程序中的各个地方,导致程序变得难以维护。宽窄接口
- wide interface——宽接口(APl)Memento角色提供的“宽接口(API)”是指所有用于获取恢复对象状态信息的方法的集合。由于宽接口(API)会暴露所有Memento角色的内部信息,因此能够使用宽接口(API)的只有Originator角色。
- narrowinterface——窄接口(API)Memento角色为外部的Caretaker角色提供了“窄接口(API)”。可以通过窄接口(API)获取的Memento角色的内部信息非常有限,因此可以有效地防止信息泄露。
通过对外提供以上两种接口(API),可以有效地防止对象的封装性被破坏
- 相关设计模式
1.Command模式(第22章)在使用Command模式处理命令时,可以使用Memento模式实现撤销功能。
2.Protype模式(第6章)在Memento模式中,为了能够实现快照和撤销功能,保存了对象当前的状态。保存的信息只是在恢复状态时所需要的那部分信息。
而在Protype模式中,会生成一个与当前实例完全相同的另外一个实例。这两个实例的内容完全一样。
- State模式(第19章)在Memento模式中,是用“实例”表示状态。而在State模式中,则是用“类”表示状态。
理清职责
- 实现功能
- ·游戏是自动进行的
- ·游戏的主人公通过掷骰子来决定下一个状态
- ·当骰子点数为1的时候,主人公的金钱会增加·当骰子点数为2的时候,主人公的金钱会减少
- ·当骰子点数为6的时候,主人公会得到水果
- ·主人公没有钱时游戏就会结束
包>>>名字=>>>说明
game |Memento|表示Gamer状态的类
game |Gamer表示游戏主人公的类。它会生成Memento的实例进行游戏的类。它会事先保存Memento的实例,之后会根据需要恢复Gamer的状态
null | MainT 这里为了方便起见使用MainT作为责任人保存用户状态
UML
时序图:
Code
- Gamer
public class Gamer {
/**
* 下面的money 与 fruits 就是按照一般的定义方式去定义
* 但是我们提取Memento的时候需要注意这个的获取规则
*/
// 获得金钱
private int money;
// 获得的水果
private List<String> fruits=new ArrayList<>();
private Random random=new Random();
private final static String[] fruitname=new String[]{
"苹果","葡萄","香蕉","橘子"
};
public Gamer(int money) {
this.money = money;
}
public int getMoney() {
return money;
}
/**
* 开始游戏
* 骰子结果1,2 ,6进行不同的操作
*/
public void bet(){
int dice=random.nextInt(6)+1;
if(dice==1){
this.money+=100;
System.out.println("金钱增加了!");
}else if(dice==2){
this.money/=2;
System.out.println("金钱减半了!");
}else if(dice==6){
String f=getFruit();
System.out.println("获得了水果["+f+"]!");
this.fruits.add(f);
}else{
System.out.println("什么也不发生");
}
}
/**
* 快照方法
*/
public Memento createMemento(){
Memento memento = new Memento(this.money);
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()){
String s = iterator.next();
if(s.startsWith("好吃的")){
memento.addFruit(s);
}
}
return memento;
}
/**
* 撤销方法
*/
public void restoreMemento(Memento memento){
this.money=memento.money;
this.fruits=memento.fruits;
}
private String getFruit() {
String prefix="";
if(random.nextBoolean()){
prefix="好吃的";
}
return prefix+fruitname[random.nextInt(fruitname.length)];
}
@Override
public String toString() {
return "Gamer{" +
"money=" + money +
", fruits=" + fruits +
'}';
}
}
- Memento
public class Memento {
/**
* 使用过程中因为Memento与Gamer是强关联关系,但是又因为是在同一个game包下,
* 使用可见性修饰符显得比较重要:
* 这里的两个字段在同一个包下都是可以访问
*/
int money;
ArrayList<String> fruits;
/**
* 窄接口
*/
public int getMoney(){
return money;
}
/**
* 这里是宽接口
* @param money
*/
Memento(int money) {
this.money = money;
this.fruits = new ArrayList<>();
}
/**
* 这里是宽接口
*/
void addFruit(String fruit){
fruits.add(fruit);
}
/**
* 这里是宽接口
*/
ArrayList<String> getFruits(){
return (ArrayList<String>) fruits.clone();
}
}
- MainT
public class MainT {
/**
* 这里的状态只是单个快照点,当你需要多个快照点的时候,
* 单独创建一个snapshot类来管理,可以使用集合等,
* 这里写个例子
*/
public static void main(String[] args) {
Gamer gamer = new Gamer(100);
//保存的一个快照 初始状态
Memento memento = gamer.createMemento();
for (int i = 0; i < 100; i++) {
System.out.println("===="+i);
System.out.println("当前状态"+gamer);
//开始游戏
gamer.bet();
System.out.println("还有多少钱"+gamer.getMoney()+"元");
if(gamer.getMoney()>memento.getMoney()){
System.out.println("//保存新状态");
memento=gamer.createMemento();
}else if(gamer.getMoney()<memento.getMoney()/2){
System.out.println("金钱减少一半了,恢复到原来的状态");
gamer.restoreMemento(memento);
}
try {
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
public class SnapShotManger implements Serializable {
private List<Memento> mementos=new ArrayList<>();
/**
* 实现java.io.Serializable接口
* 用objectoutputstream的writeobject方法
* 用objectInputStream的 readobject方法
*/
/**
* 保存
*/
/**
* 恢复
*/
}
Memento模式(备忘录设计模式)的更多相关文章
- 《图解设计模式》读书笔记8-2 MEMENTO模式
目录 Memento模式 示例代码 程序类图 代码 角色和类图 模式类图 角色 思路拓展 接口可见性 保存多少个Memento 划分Caretaker和Originator的意义 Memento模式 ...
- Java设计模式(15)备忘录模式(Memento模式)
Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public class ...
- C++设计模式实现--备忘录(Memento)模式
一. 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态.并在该对象之外保存这个状态. 这样以后就可将该对象恢复到原先保存的状态. 结构图: 使用范围: Memento 模式比較适用于功 ...
- 设计模式C++描述----17.备忘录(Memento)模式
一. 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 结构图: 使用范围: Memento 模式比较适用于功能 ...
- 设计模式之美:Memento(备忘录)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Memento 模式结构样式代码. 别名 Token 意图 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这 ...
- 备忘录(Memento)模式
备忘录模式又叫做快照模式或者Token模式. 备忘录对象是一个用来存储另一个对象内部状态的快照的对象.备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉住,并外部化,存储起来,从而可以在将来 ...
- 设计模式之——Memento模式
Memento模式即快照模式,就是在某一时刻,设定一个状态,在后面随时可以返回到当前状态的模式. 我们拿一个闯关游戏作为举例,一共有十关,每闯一关,玩家所持金额增加一百,而闯关失败就扣一百.初始时,给 ...
- 设计模式(十八)Memento模式
在使用面向对象编程的方式实现撤销功能时,需要事先保存实例的相关状态信息.然后,在撤销时,还需要根据所保存的信息将实例恢复至原来的状态. 要想恢复实例,需要一个可以自由访问实例内部结构的权限.但是,如果 ...
- 【行为型】Memento模式
备忘录模式顾名思义就是一种能有备忘作用的设计模式,其目的是在对象外部保存其在某一时刻的状态信息,并且在任何需要的时候,都可以通过备忘录中保存的状态数据恢复对象在当时情形下的状态. 备忘录模式旨在对象的 ...
随机推荐
- FFmpeg 的sws_getContext函数 、sws_scale函数
FFmpeg里面的sws_scale库可以在一个函数里面同时实现:1.图像色彩空间转换:2.分辨率缩放:3.前后图像滤波处理. 其核心函数主要有三个: // 初始化sws_scalestruct Sw ...
- Agc016_D XOR Replace
传送门 题目大意 给定两个长为$n$的序列$A,B$你可以进行若干组操作,每次操作选定一各位置$x$,令$A_x$等于$A$的异或和. 问能否通过一定操作使得$A$成为$B$,如果能,求最小操作书数. ...
- java多线程编程核心技术——第二章总结
第一节synchronized同步方法目录 1.1方法内的变量为线程安全的 1.2实例变量非线程安全 1.3多个对象多个锁 1.4synchronized方法与锁对象 1.5脏读 1.6synchro ...
- java blob 文件上传下载
1.文件上传 pojo中为byte[] 类型,数据库中对应为blob类型. 主要代码: FileInputStream fis = null; fis = new FileInputStream(ne ...
- springMVC绑定json参数之二(2.1)
二.springmvc 接收不同格式的json字符串 1.首先扫盲几个知识点: 这个绑定json参数讲的都是用@RequestBody标签,所以前台必须传json字符串,不能是json对象,但是如果不 ...
- linux命令-任务计划-cron
任务计划,有时间规律的执行某些事情. 查看任务计划:crontab -l 指定用户:crontab -l -u 用户名 该用户没有任务计划. 自定义任务计划 进入一个操作和vim类似的界面 用空格分 ...
- USACO-Your Ride Is Here(你的飞碟在这儿)-Section1.2<1>
[英文原题] Your Ride Is Here It is a well-known fact that behind every good comet is a UFO. These UFOs o ...
- 1、Question: prep_reads.info vs. align_summary.txt
###参考:https://www.biostars.org/p/163356/ used TopHat to map my reads against their relative referenc ...
- 文件格式——gff格式
Gff文件格式 gff格式是Sanger研究所定义,是一种简单的.方便的对于DNA.RNA以及蛋白质序列的特征进行描述的一种数据格式,已经成为序列注释的通用格式,比如基因组的基因预测,许多软件都支持输 ...
- 【BZOJ2839】集合计数 组合数+容斥
[BZOJ2839]集合计数 Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数 ...