版权声明:转载必须注明本文转自晓_晨的博客:http://blog.csdn.net/niunai112
目录
导航
设计模式之六大设计原则
设计模式(一)单例模式
设计模式(二)工厂模式
设计模式(三)策略模式
设计模式(四)适配器模式
设计模式(五)享元模式
设计模式(六)建造者模式
设计模式(七)原型模式
设计模式(八)桥接模式
设计模式(九)外观模式
设计模式(十)组合模式
设计模式(十一)装饰器模式
设计模式(十二)代理模式
设计模式(十三)迭代器模式
设计模式(十四)观察者模式
设计模式(十五)中介者模式
设计模式(十六)命令模式
设计模式(十七)状态模式
设计模式(十八)访问者模式
设计模式(十九)责任链模式
设计模式(二十)解释器模式
设计模式(二十一)备忘录模式
设计模式(二十二)模板模式
设计模式总结篇(为什么要学习设计模式,学习设计模式的好处)
前言
备忘录模式(Memento Pattern):保存一个对象的某个状态,以便在适当的时候恢复对象。
备忘录角色(Memento):保存需要保存的所有状态,将其抽象成一个备忘录角色。
备忘发起角色(Originator):需要被备忘录记录状态并保存的角色,可以创建一个备忘录,用以记录当前时刻它的内部状态,可以使用备忘录恢复内部状态。
备忘录管理者角色(Caretaker):负责管理备忘录。不能对备忘录的内容进行操作或检查。只有保存和返回备忘录角色的功能。
例子
LZ以一部动漫为例子,LZ认为这部动漫能很好的体现这个模式,那就是《从零开始异世界》,相信很多人应该看过,若没有看过的,可以以游戏来替换。
里面的主角486,一开始的时候,总是不停的死亡,然后从某一时刻复活,然后继续。这个过程用备忘录模式来实现,就是
白箱实现,顾名思义,我们的Memento对象是完全对使用者开放的,使用者能直接看到Memento,以及直接对Memento 进行操作。
/***
*
*@Author ChenjunWang
*@Description:备忘录模板(要返回的记录以这个格式保存)
*@Date: Created in 10:57 2018/4/18
*@Modified By:
*
*/
public class Memento {
private int time;
public Memento(int time) {
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
}
/***
*
*@Author ChenjunWang
*@Description:备忘录发起者,也是需要被备忘的对象
*@Date: Created in 10:57 2018/4/18
*@Modified By:
*
*/
public class Originator {
private int time = 0;//刚进入的时候,486的时间节点是0
public Memento creatMementoObject() {
return new Memento(time);
}
public void restoreMemento(Memento memento) {
this.time = memento.getTime();
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
}
/***
*
*@Author ChenjunWang
*@Description:看门人(负责备忘录的管理)
*@Date: Created in 10:58 2018/4/18
*@Modified By:
*
*/
public class Caretaker {
private Memento memento;
//返回已保存的备忘录(用于恢复记录)
public Memento retrieveMemento(){
return this.memento;
}
//保存备忘录记录
public void saveMemento(Memento memento) {
this.memento = memento;
}
}
/***
*
*@Author ChenjunWang
*@Description:
*@Date: Created in 11:26 2018/4/18
*@Modified By:
*
*/
public class Test {
public static void main(String[] args) {
Originator u486 = new Originator();
Caretaker admin = new Caretaker();
System.out.println("------------------486 来到了异世界----------------------");
admin.saveMemento(u486.creatMementoObject());
u486.setTime(100);
System.out.println("------------------486 death----------------------");
u486.restoreMemento(admin.retrieveMemento());
System.out.println("-------------------从零开始-----------------------");
System.out.println("486的时间变为:" + u486.getTime());
}
}
运行结果如下
-----------------------------------------------------------------
------------------486 来到了异世界----------------------
------------------486 death----------------------
-------------------从零开始-----------------------
486的时间变为:0
黑箱实现,只需要把Memento替换成IMemento接口,把Originator替换即可。
/***
*
*@Author ChenjunWang
*@Description:备忘录模板(要返回的记录以这个格式保存)
*@Date: Created in 10:57 2018/4/18
*@Modified By:
*
*/
public interface IMemento {
}
/***
*
*@Author ChenjunWang
*@Description:
*@Date: Created in 10:57 2018/4/18
*@Modified By:
*
*/
public class Originator {
private int time = 0;
public IMemento creatMementoObject() {
return new Memento(time);
}
public void restoreMemento(IMemento memento) {
this.time = ((Memento)memento).getTime();
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
private class Memento implements IMemento{
private int time;
public Memento(int time) {
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
}
}
/***
*
*@Author ChenjunWang
*@Description:测试类
*@Date: Created in 11:26 2018/4/18
*@Modified By:
*
*/
public class Test {
public static void main(String[] args) {
Originator u486 = new Originator();
Caretaker admin = new Caretaker();
System.out.println("------------------486 来到了异世界----------------------");
admin.saveMemento(u486.creatMementoObject());
u486.setTime(100);
System.out.println("------------------486 death----------------------");
u486.restoreMemento(admin.retrieveMemento());
System.out.println("-------------------从零开始-----------------------");
System.out.println("486的时间变为:" + u486.getTime());
}
}
运行结果如下
---------------------------------------------------
------------------486 来到了异世界----------------------
------------------486 death----------------------
-------------------从零开始-----------------------
486的时间变为:0
在黑箱里,我们只传递IMemento,不需要知道里面的结构就是怎么样的, 因为Memento是内部类,被Originator隐藏在里面,解析也是通过Originator自己解析然后使用的,更加符合安全性,最小可见性这些要求。
以上两个代码都只是实线了单点存储,即只能保存一个状态,假如要保存多个状态,其实也很简单,LZ在这个点就不展开讲了,大家如果觉得有必要的话,可以在我的基础上进行拓展,基本就是用个数据结构来存储,比如List,或者Map,然后存和取的代码进行相应调整即可。
总结
优点
(1)提供了一种可以恢复状态的机制,可以使用户回到之前存储过的状态。
缺点
(1)需要消耗额外的空间来存放要保存状态信息,如果需要保存掉的类的成员信息很多,如果是多点记录保存,那用在存储状态所用的资源也是很巨大的。(实现了某种功能肯定是有付出的,当LZ觉得比起付出,备忘录模式的回报在关键时刻决定是非常非常有用的486靠这个保命,你说重不重要)
Git地址
本篇实例Github地址:https://github.com/stackisok/Design-Pattern/tree/master/src/memento
有什么不懂或者不对的地方,欢迎留言。
喜欢LZ文章的小伙伴们,可以关注一波,也可以留言,LZ会回你们的。
觉得写得不错的小伙伴,欢迎转载,但请附上原文地址,谢谢^_^!