您的位置:首页 > 其它

设计模式-备忘录模式

2017-06-12 16:03 218 查看

设计模式-备忘录模式

概念

所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

优点

1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
2、实现了信息的封装,使得用户不需要关心状态的保存细节。

缺点

消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

使用场景

很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。

角色

Memento 包含了要被恢复的对象的状态。
Originator 创建并在 Memento 对象中存储状态。
Caretaker 对象负责从 Memento 中恢复对象的状态。

案例描述

一个学生在看金庸武侠电子书,到做饭点保存进度,吃完饭恢复进度继续看

UML类图



代码解析UML类图

Memento 包含了要被恢复的对象的状态。

/**
* 设计模式-备忘录模式-Memento
*
* 电子书备忘录
*
* Created by laizhiyuan on 2017/6/12.
*/
public class EBookMemento {

/**
* 保存行数属性
*/
private int rowNumber;

public EBookMemento(int rowNumber) {
this.rowNumber = rowNumber;
}

public int getRowNumber() {
return rowNumber;
}
}


Originator 创建并在 Memento 对象中存储状态。

/**
* 设计模式-备忘录模式-Originator
*
* 电子书
*
* Created by laizhiyuan on 2017/6/12.
*/
public class EBookOriginator {

/**
* 行数
*/
private int rowNumber;

/**
* 保存进度
*
* @return
*/
public EBookMemento saveProgress(){
return new EBookMemento(this.rowNumber);
}

/**
* 恢复进度
*
* @param eBookMemento
*/
public void progress(EBookMemento eBookMemento){
setRowNumber(eBookMemento.getRowNumber());
}

public int getRowNumber() {
return rowNumber;
}

public void setRowNumber(int rowNumber) {
this.rowNumber = rowNumber;
}
}


Caretaker 对象负责从 Memento 中恢复对象的状态。

/**
* 设计模式-备忘录模式-Caretaker
*
* 管理电子书备忘录
*
* Created by laizhiyuan on 2017/6/12.
*/
public class EBookCaretaker {

private EBookMemento eBookMemento;

public EBookMemento geteBookMemento() {
return eBookMemento;
}

public void seteBookMemento(EBookMemento eBookMemento) {
this.eBookMemento = eBookMemento;
}
}


测试

/**
* 测试
*
* Created by laizhiyuan on 2017/6/12.
*/
public class Main {

public static void main(String[] args) {

EBookOriginator eBook = new EBookOriginator();

/**
* 早上八点开始看
*/
int yema = 0;
int time = 8;

eBook.setRowNumber(yema);
while (time < 11){

try {
/**
* 一小时十页
*/
eBook.setRowNumber(eBook.getRowNumber() + 10);

System.out.println("看书中.....");
Thread.sleep(1000);
System.out.println("过了一个小时");
time += 1;
} catch (InterruptedException e) {
e.printStackTrace();
}
}

EBookCaretaker caretaker = new EBookCaretaker();
caretaker.seteBookMemento(eBook.saveProgress());

System.out.println("当前页码:" + eBook.getRowNumber() + "\t当前时间:" + time + "点 \t 保存进度,准备做饭去");

try {
Thread.sleep(2000);
time += 2;

eBook.progress(caretaker.geteBookMemento());
/**
* 看小说都是好有精神的,都不用午休的
*/
System.out.printf("吃完饭继续看书,恢复上次进度页码: " + eBook.getRowNumber());

} catch (InterruptedException e) {
e.printStackTrace();
}

}
}


控制台输出

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: