浅谈Java设计模式——备忘录模式(Memento)
一、概述
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。它实现了对信息的封装,使得客户不需要关心状态保存的细节。保存就要消耗资源,所以备忘录模式的缺点就在于消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
二、使用场景
1.必须保存一个对象在某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。
2.如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
三、参与者
1.Memento 备忘录存储原发器对象的内部状态。
2.Originator 原发器创建一个备忘录,用以记录当前时刻它的内部状态。 使用备忘录恢复内部状态.。
3.Caretaker 负责保存好备忘录。 不能对备忘录的内容进行操作或检查。
四、类图
五、示例代码
1.Memento
/**
* Memento
* @author zhipeng_Tong
*/
public class RoleStateMemento {
private int liftValue;
private int attachPower;
private int defensivePower;
public RoleStateMemento(int liftValue, int attachPower, int defensivePower) {
this.liftValue = liftValue;
this.attachPower = attachPower;
this.defensivePower = defensivePower;
}
public int getLiftValue() {
return liftValue;
}
public void setLiftValue(int liftValue) {
this.liftValue = liftValue;
}
public int getAttachPower() {
return attachPower;
}
public void setAttachPower(int attachPower) {
this.attachPower = attachPower;
}
public int getDefensivePower() {
return defensivePower;
}
public void setDefensivePower(int defensivePower) {
this.defensivePower = defensivePower;
}
}
2.Originator
/**
* Originator
* @author zhipeng_Tong
*/
public class GameRole {
private int liftValue; // 生命值
private int attachPower; // 攻击力
private int defensivePower; // 防御力
public int getLiftValue() {
return liftValue;
}
public void setLiftValue(int liftValue) {
this.liftValue = liftValue;
}
public int getAttachPower() {
return attachPower;
}
public void setAttachPower(int attachPower) {
this.attachPower = attachPower;
}
public int getDefensivePower() {
return defensivePower;
}
public void setDefensivePower(int defensivePower) {
this.defensivePower = defensivePower;
}
// 展示状态
public void displayState() {
System.out.println("角色状态信息: ");
System.out.println(String.format("生命值: %d", liftValue));
System.out.println(String.format("攻击力: %d", attachPower));
System.out.println(String.format("防御力: %d", attachPower));
}
// 初始化状态
public void initialState() {
this.liftValue = 100;
this.attachPower = 100;
this.defensivePower = 100;
}
// 战斗
public void fight() {
this.liftValue = 0;
this.attachPower = 0;
this.defensivePower = 0;
}
// 保存角色状态
public RoleStateMemento saveState() {
return new RoleStateMemento(this.liftValue, this.attachPower, this.defensivePower);
}
// 回复角色状态
public void recoveryState(RoleStateMemento memento) {
this.liftValue = memento.getLiftValue();
this.attachPower = memento.getAttachPower();
this.defensivePower = memento.getDefensivePower();
}
}
3.Caretaker
/**
* Caretaker
* @author zhipeng_Tong
*/
public class RoleStateCaretaker {
private RoleStateMemento memento;
public RoleStateMemento getMemento() {
return memento;
}
public void setMemento(RoleStateMemento memento) {
this.memento = memento;
}
}
4.测试代码
public class Client {
public static void main(String[] args) {
// 大战boss前
// 初始化游戏角色初始状态,三项指标都为100
GameRole gameRole = new GameRole();
gameRole.initialState();
gameRole.displayState();
// 保存进度信息
RoleStateCaretaker caretaker = new RoleStateCaretaker();
caretaker.setMemento(gameRole.saveState());
// 大战boss,损耗严重
gameRole.fight();
gameRole.displayState();
// 回复到之前状态
gameRole.recoveryState(caretaker.getMemento());
gameRole.displayState();
}
}
运行结果:
角色状态信息:
生命值: 100
攻击力: 100
防御力: 100
角色状态信息:
生命值: 0
攻击力: 0
防御力: 0
角色状态信息:
生命值: 100
攻击力: 100
防御力: 100