[设计模式]备忘录模式
2016-08-22 21:54
288 查看
感谢《Android源码设计模式解析与实战》 何红辉 关爱民 著
备忘录模式是一种行为模式,该模式用于保存对象当前状态,,,并且在之后可以再次恢复到此状态,这有点像我们平时说的“后悔药”。备忘录模式实现的方式需要保证被保存的对象状态不能被对象从外部访问,目的是为了保护好被保存的这些对象状态的完整性以及内部实现不向外暴露。
定义:
在不破坏封装的前提下,捕获一个对象内部状态,并在该对象之外保存这个状态,这样,以后就可将该对象恢复到原先保存的状态。
使用场景:
1.需要保存一个对象在某一个时刻的状态或部分状态。
2.如果用一个接口来让其他对象得到这些状态,,将会暴露对象的实现细节并破坏对象的封装性,一个对象不希望外界直接访问其内部状态,通过中间对象可以间接访问其内部状态。
UML类图:
Originator:负责创建一个备忘录,可以记录、恢复自身的内部状态。同时Originator还可以根据需要决定Memento存储自身的内部状态。
Memento:备忘录角色,用于存储Originator的内部状态,并且可以防止Originator以外的对象访问Memento。
Caretaker:负责存储备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象。
示例:
总结:
备忘录模式是在一破坏封装的条件下,,通过备忘录对象(Memotto)存储另外一个对象内部状态的快照,在将来合适的时候把这个对象还原到存储起来的状态。
优点:
1.给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
2.实现了信息的封装,使得用户不需要关心状态的保存细节。
缺点:
消耗资源,如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
备忘录模式是一种行为模式,该模式用于保存对象当前状态,,,并且在之后可以再次恢复到此状态,这有点像我们平时说的“后悔药”。备忘录模式实现的方式需要保证被保存的对象状态不能被对象从外部访问,目的是为了保护好被保存的这些对象状态的完整性以及内部实现不向外暴露。
定义:
在不破坏封装的前提下,捕获一个对象内部状态,并在该对象之外保存这个状态,这样,以后就可将该对象恢复到原先保存的状态。
使用场景:
1.需要保存一个对象在某一个时刻的状态或部分状态。
2.如果用一个接口来让其他对象得到这些状态,,将会暴露对象的实现细节并破坏对象的封装性,一个对象不希望外界直接访问其内部状态,通过中间对象可以间接访问其内部状态。
UML类图:
Originator:负责创建一个备忘录,可以记录、恢复自身的内部状态。同时Originator还可以根据需要决定Memento存储自身的内部状态。
Memento:备忘录角色,用于存储Originator的内部状态,并且可以防止Originator以外的对象访问Memento。
Caretaker:负责存储备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象。
示例:
/** * 游戏类 * @author Administrator * *本类中存储了几个关键字段,关卡、人物的生命值、武器,当调用play函数玩游戏时,我们对关卡和人物的生命值进行修改。 *在该类中可以通过createMemoto函数来创建该用户的备忘录对象,也就是将自身的状态保存到一个Memoto对象中。外部 *可以通过restore方法将CallOfDuty对象的状态从备忘录对象中恢复 */ public class CallOfDuty { private int mCheckpoint = 1; private int mLifeValue = 100; private String mWeapon = "沙漠之鹰"; public void play(){ System.out.println("玩游戏:" +String.format("第%d关",mCheckpoint)); mLifeValue -=10; System.out.println("升级啦"); mCheckpoint++; System.out.println("到达:" + String.format("第%d关",mCheckpoint)); } public void quit(){ System.out.println("----------"); System.out.println("退出游戏前的游戏属性:" + this.toString()); System.out.println("退出游戏"); System.out.println("----------"); } /** * 创建备忘录 * @return */ public Memoto createMemoto(){ Memoto memoto = new Memoto(); memoto.mCheckpoint = mCheckpoint; memoto.mLifeValue = mLifeValue; memoto.mWeapon = mWeapon; return memoto; } public void restore(Memoto memoto){ this.mCheckpoint = memoto.mCheckpoint; this.mLifeValue = memoto.mLifeValue; this.mWeapon = memoto.mWeapon; System.out.println("恢复后的属性:" + this.toString()); } public String toString(){ return "CallOfDuty [mCheckponit=" + mCheckpoint +", mLifeValue=" + mLifeValue + ", mWeapon=" + mWeapon + "]"; } }
/** * 无状态、无操作的实体类,负责管理Memoto * @author Administrator *只负责用来存储Originator角色的一些数据,防止外部直接访问Originator */ public class Caretaker { Memoto mMemoto; //备忘录 /** * 存档 * @param memoto */ public void archive(Memoto memoto){ this.mMemoto = memoto; } public Memoto getMemoto(){ return mMemoto; } }
/** * 备忘录类 * @author Administrator *它只是存储CallOfDuty对象的字段 */ public class Memoto { public int mCheckpoint; public int mLifeValue; public String mWeapon; @Override public String toString() { return "Memoto [mCheckpoint=" + mCheckpoint + ", mLifeValue=" + mLifeValue + ", mWeapon=" + mWeapon + "]"; } }
public class Client { public static void main(String[] args) { //构建游戏对象 CallOfDuty game = new CallOfDuty(); //打游戏 game.play(); Caretaker caretaker = new Caretaker(); //游戏存档 caretaker.archive(game.createMemoto()); //退出游戏 game.quit(); CallOfDuty newGame = new CallOfDuty(); newGame.restore(caretaker.getMemoto()); } //CallOfDuty在这里为Originator角色,也就是需要存储数据的对象,在这里并没有直接存储CallOfDuty //的对象,而是通过Memoto对CallOfDuty对象的数据进行存储,然后再存储Memmoto对象,,最终对Memoto的存取操作 //则交给Caretaker对象。 //这个过程中,各个角色职责清晰、单一,代码也比较简单即对外屏蔽了对CallOfDuty角色的直接访问,在满足了对象状态存取功能的 //同时也使得该模韦伯 结构保持清晰、整洁。 }
总结:
备忘录模式是在一破坏封装的条件下,,通过备忘录对象(Memotto)存储另外一个对象内部状态的快照,在将来合适的时候把这个对象还原到存储起来的状态。
优点:
1.给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
2.实现了信息的封装,使得用户不需要关心状态的保存细节。
缺点:
消耗资源,如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
相关文章推荐
- [读书笔记] 深入探索C++对象模型-第二章《构造函数语义学》(上)
- 【机器学习】神经网络(二)——反向传播算法
- 快嘉开发框架脚手架release1.1发布及使用说明
- 页结构
- Spring_Bean 的作用域
- Cpp_Primer--Arrays
- 线程安全和可重入
- android 利用AIDL实现Binder跨进程通信
- Python——图片转字符小工具
- 《伏牛传》:善用移动互联网造势,迎合小众而不是大众口味的餐饮业的尝试,目测作者的商业洞察力强过李善友和罗振宇。3星
- K均值聚类
- Leetcode-344-Reverse String
- 【Ceph专题】 Ceph架构详细分析
- 1.5 Arduino的第一个程序
- [gym 101047C Robotics Competition] 矩阵快速幂求解点旋转平移N次之后的位置
- 【有感】今日阅读我知乎轮子哥“vczh”故事有感
- 【Ceph专题】 Ceph架构详细分析
- codeforce 417D Cunning Gena (状压DP)
- APicloud商品详情界面
- 学习注水-20160822-CCNA To CCNP 日结小记-高级eigrp/用于IPv6的EIGRP及命名EIGRP的层级结构