备忘录模式(Memento) 属于对象的行为模式。
备忘录模式是我觉得最容易理解的一种模式,它的名字取得非常的贴切。
1. 定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
2. 使用的原因
想要恢复对象某时的原有状态.
memento是一个保存另外一个对象内部状态拷贝的对象.这样以后就可以将该对象恢复到原先保存的状态.
3. 适用的情况举例
有很多备忘录模式的应用,只是我们已经见过,却没细想这是备忘录模式的使用罢了,略略举几例:
eg1. 备忘录在jsp+javabean的使用:
在一系统中新增帐户时,在表单中需要填写用户名、密码、联系电话、地址等信息,如果有些字段没有填写或填写错误,当用户点击“提交”按钮时,需要在新增页 面上保存用户输入的选项,并提示出错的选项。这就是利用JavaBean的scope="request"或scope="session"特性实现的, 即是用备忘录模式实现的。
eg2. 修理汽车的刹车时。首先移开两边的挡板,露出左右刹车片。只能卸下一片,这时另一片作为一个备忘录来表明刹车是怎样安装的。在这片修理完成后,才可以卸下另一片。当第二片卸下时,第一片就成了备忘录。
eg3. 都说人生没有后悔药可买,我们都在为所做的事付出着代价,但在软世界里却有“后悔药”,我改变了某东西的某些状态之后,只要我们之前保存了该东西的某状 态,我们就可以通过备忘录模式实现该东西的状态还原,其实这何尝不是一个能使时光倒流的“月光宝盒”,总“神奇”一词了得。
4. 类图结构及说明
1)类图如下所示:
2)类说明
i)Memento:备忘录角色, 主要负责的工作如下:
将发起人对象的内部状态存储起来;
可以保护其内容不被发起人(Originator)对象之外的任何对象所读取。
ii)Originator:发起人角色,主要完成如下工作:
创建一个含有当前的内部状态的备忘录对象;
使用备忘录对象存储其内部状态。
iii)Caretaker:负责人角色,完成工作如下:
负责保存备忘录对象;
不保存备忘录对象的内容。
5. 使用举例
1)需求
Amigo的mother对Amigo当前的状态很不满意:不爱打扮,做事拖拖拉拉,十足马大哈。该mother想对Amigo进行改造,但又唯恐改造后还不如从前的Amigo好,有可能需要实现“时光倒流”功能。
2)分析
经过细细分析,这个状态保存功能其实可以通过备忘录模式来得到很好的实现,可通过备忘录来保存Amigo当前的状态:不爱打扮,做事拖拖拉拉,十足马大 哈,以及其它的N多优点(哈哈哈。。。),如果改造后的Amigo不如从前,那我们让我们的“月光宝盒”来实现一下“时光倒流”,真神奇啊。。。
3)代码参考实现
i)发起人角色
public class Originator {
private String state;
/**
* 工厂方法,返回一个新的备忘录对象
*/
public Memento createMemento {
return new Memento(state);
}
/**
* 将发起人恢复到备忘录对象所记载的状态
*/
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
//省略状态state的getter和setter方法
}
ii)备忘录角色
public class Memento {
private String state;
/**
* 构造函数
*/
public Memento(String state) {
this.state = state;
}
//省略state的getter和setter方法
}
iii)负责人角色
public class Caretaker {
private Memento memento;
/**
* 备忘录的取值方法
*/
public Memento retrieveMemento {
return this.memento;
}
/**
* 备忘录的保存方法
*/
public void saveMemento(Memento memento) {
this.memento = memento;
}
}
iv)客户端模拟实现
public class Client {
private static Originator ori = new Originator();
private static Caretaker taker = new Caretaker();
public static void main(String[] args) {
//amigo当前的状态
ori.setState("不爱打扮,做事拖拖拉拉,十足马大哈");
//保存amigo当前的状态
taker.saveMemento(ori.createMemento());
//mother要对amigo进行改造
ori.setState("穿着时髦,做事精练");
//mother发现改造后产生了很多副作用,于是反悔了,要恢复女儿以前的样子
ori.restoreMemento(taker.retrieveMemento());
//amigo被打回原型,^_^
System.out.println("amigo当前情况: " + ori.getState());
}
}
五、Memento模式的特点:
在需要提供保存、恢复对象状态的类中,必须提供两个方法:
.保存对象当前状态方法:将对象自身(this)作为参数传入,创建备忘录。
.恢复对象之前状态的方法:取出备忘录/接收一个备忘录对象,从中获取对象之前的状态
模式的缺点是耗费大,如果内部状态很多,再保存一份,无意要浪费大量内存.
注意:Memento模式保存的是操作前对象的状态,而不是操作后对象的状态;否则就没办法做恢复了.
备忘录模式是我觉得最容易理解的一种模式,它的名字取得非常的贴切。
1. 定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
2. 使用的原因
想要恢复对象某时的原有状态.
memento是一个保存另外一个对象内部状态拷贝的对象.这样以后就可以将该对象恢复到原先保存的状态.
3. 适用的情况举例
有很多备忘录模式的应用,只是我们已经见过,却没细想这是备忘录模式的使用罢了,略略举几例:
eg1. 备忘录在jsp+javabean的使用:
在一系统中新增帐户时,在表单中需要填写用户名、密码、联系电话、地址等信息,如果有些字段没有填写或填写错误,当用户点击“提交”按钮时,需要在新增页 面上保存用户输入的选项,并提示出错的选项。这就是利用JavaBean的scope="request"或scope="session"特性实现的, 即是用备忘录模式实现的。
eg2. 修理汽车的刹车时。首先移开两边的挡板,露出左右刹车片。只能卸下一片,这时另一片作为一个备忘录来表明刹车是怎样安装的。在这片修理完成后,才可以卸下另一片。当第二片卸下时,第一片就成了备忘录。
eg3. 都说人生没有后悔药可买,我们都在为所做的事付出着代价,但在软世界里却有“后悔药”,我改变了某东西的某些状态之后,只要我们之前保存了该东西的某状 态,我们就可以通过备忘录模式实现该东西的状态还原,其实这何尝不是一个能使时光倒流的“月光宝盒”,总“神奇”一词了得。
4. 类图结构及说明
1)类图如下所示:
![java 设计模式 行为模式 -Memento(备忘录模式) - 最接近神的人 - 最接近神的人](http://img306.ph.126.net/WIi_WZItEmjHwuBVkUyGQg==/3862681105401043080.bmp)
2)类说明
i)Memento:备忘录角色, 主要负责的工作如下:
将发起人对象的内部状态存储起来;
可以保护其内容不被发起人(Originator)对象之外的任何对象所读取。
ii)Originator:发起人角色,主要完成如下工作:
创建一个含有当前的内部状态的备忘录对象;
使用备忘录对象存储其内部状态。
iii)Caretaker:负责人角色,完成工作如下:
负责保存备忘录对象;
不保存备忘录对象的内容。
5. 使用举例
1)需求
Amigo的mother对Amigo当前的状态很不满意:不爱打扮,做事拖拖拉拉,十足马大哈。该mother想对Amigo进行改造,但又唯恐改造后还不如从前的Amigo好,有可能需要实现“时光倒流”功能。
2)分析
经过细细分析,这个状态保存功能其实可以通过备忘录模式来得到很好的实现,可通过备忘录来保存Amigo当前的状态:不爱打扮,做事拖拖拉拉,十足马大 哈,以及其它的N多优点(哈哈哈。。。),如果改造后的Amigo不如从前,那我们让我们的“月光宝盒”来实现一下“时光倒流”,真神奇啊。。。
3)代码参考实现
i)发起人角色
public class Originator {
private String state;
/**
* 工厂方法,返回一个新的备忘录对象
*/
public Memento createMemento {
return new Memento(state);
}
/**
* 将发起人恢复到备忘录对象所记载的状态
*/
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
//省略状态state的getter和setter方法
}
ii)备忘录角色
public class Memento {
private String state;
/**
* 构造函数
*/
public Memento(String state) {
this.state = state;
}
//省略state的getter和setter方法
}
iii)负责人角色
public class Caretaker {
private Memento memento;
/**
* 备忘录的取值方法
*/
public Memento retrieveMemento {
return this.memento;
}
/**
* 备忘录的保存方法
*/
public void saveMemento(Memento memento) {
this.memento = memento;
}
}
iv)客户端模拟实现
public class Client {
private static Originator ori = new Originator();
private static Caretaker taker = new Caretaker();
public static void main(String[] args) {
//amigo当前的状态
ori.setState("不爱打扮,做事拖拖拉拉,十足马大哈");
//保存amigo当前的状态
taker.saveMemento(ori.createMemento());
//mother要对amigo进行改造
ori.setState("穿着时髦,做事精练");
//mother发现改造后产生了很多副作用,于是反悔了,要恢复女儿以前的样子
ori.restoreMemento(taker.retrieveMemento());
//amigo被打回原型,^_^
System.out.println("amigo当前情况: " + ori.getState());
}
}
在需要提供保存、恢复对象状态的类中,必须提供两个方法:
.保存对象当前状态方法:将对象自身(this)作为参数传入,创建备忘录。
.恢复对象之前状态的方法:取出备忘录/接收一个备忘录对象,从中获取对象之前的状态
模式的缺点是耗费大,如果内部状态很多,再保存一份,无意要浪费大量内存.
注意:Memento模式保存的是操作前对象的状态,而不是操作后对象的状态;否则就没办法做恢复了.