前言
最近小咸儿又开始和小伙伴们一起学习设计模式了,这次学习的是备忘录模式,话不多说,直接进入正题。
叙述
定义
备忘录模式(Memento Pattern):在不破坏封装性的前提下捕获一个对象内部的状态,并在对象之外保存这个状态,以便对象以后恢复到这一状态。
备忘录模式属于行为模式
备忘录模式中,客户不与备忘录耦合,与备忘录管理类耦合
UML图
图中的角色:
发起类(Originator):创建一个备忘录对象,使用备忘录存储它的内部状态。
备忘录(Memento):将发起类的内部状态存储起来,发起类根据需要决定备忘录存储发起者的哪些内部状态。不直接和其他类交互
管理者类(Caretaker): 保存备忘录,但是不对备忘录操作或检查
示例
在打游戏的过程中,去打大boss前,往往会先将角色当前的状态保存下来,以备在打完boss未成功时恢复到之前的状态。接下来就是以这个小demo为例:
代码实现
发起者:GameRole
package pattern.builder.meomory;
/**
* 游戏角色
* @author Phyllis
* @date 2019年7月6日15:54:06
*/
public class GameRole {
private int vit;
private int atk;
/**
* 初始化角色状态
*/
public void init(){
vit = 100;
atk = 100;
}
/**
* 显示角色状态
*/
public void show() {
System.out.println("体力:"+vit);
System.out.println("攻击力:"+atk);
}
public void fightBoss(){
this.vit = 0;
this.atk = 0;
}
/**
* 创建备忘录
* @return 备忘录保存结果
*/
public RoleStateMemento saveMemento(){
return (new RoleStateMemento(vit,atk));
}
/**
* 恢复备忘录中原来保存的内容
* @param roleSateMemento 备忘录
*/
public void recover(RoleStateMemento roleSateMemento){
this.vit = roleSateMemento.getVit();
this.atk = roleSateMemento.getAtk();
}
}
备忘录:RoleStateMemento
package pattern.builder.meomory;
/**
* 存储类:备忘录
* @author Phyllis
* @date 2019年7月6日16:01:30
*/
public class RoleStateMemento {
private int vit;
private int atk;
public RoleStateMemento(int vit, int atk){
this.vit = vit;
this.atk = atk;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk = atk;
}
public int getVit() {
return vit;
}
public void setVit(int vit) {
this.vit = vit;
}
}
管理者:RoleStateMange
package pattern.builder.meomory;
/**
* 游戏角色管理
* @author Phyllis
* @date 2019年7月6日16:05:27
*/
public class RoleStateMange {
private RoleStateMemento memento;
public RoleStateMemento getMemento() {
return memento;
}
public void setMemento(RoleStateMemento memento) {
this.memento = memento;
}
}
客户端:Client
package pattern.builder.meomory;
/**
* 客户端:备忘录模式
* @author Phyllis
* @date 2019年7月6日16:07:15
*/
public class Client {
public static void main(String[] args){
GameRole liaowp = new GameRole();
liaowp.init();
liaowp.show();
RoleStateMange adminMange = new RoleStateMange();
// 保存
adminMange.setMemento(liaowp.saveMemento());
liaowp.fightBoss();
liaowp.show();
liaowp.recover(adminMange.getMemento());
liaowp.show();
}
}
优点
- 将被存储的状态放在外面,不要和关键对象混在一起,这可以帮助维护内聚
- 保持关键对象的数据封装
- 提供了容易实现的恢复能力
用途和缺点
- 备忘录用于存储状态
- 使用备忘录的缺点:存储和恢复状态的过程可能相当耗时
- 在java系统中,其实可以考虑使用序列化(serialization)机制存储系统的状态
总结
适用场景:
- 保存一个对象在某个时刻的全部状态或部分状态,这样以后需要时它能够恢复到先前的状态,实现撤销操作。
- 防止外界对象破坏一个对象历史状态的封装性,避免将对象历史状态的实现细节暴露给外界对象。
感谢您的阅读~~