概念
我们经常玩实时战略游戏,一般在完成大的战役前,我们会将大战前的信息保存一下,以便挂掉时恢复再来一次。那么我们要保存信息怎么存和怎么对这些信息进行操作,就要用到备忘录模式。备忘录模式独立出来一个数据载体,这个载体就叫备忘录,它记录了某一个时刻系统的特征参数。然后我们将备忘录交给一个管理者进行存储管理,管理者并不明白备忘录各种特征参数的含义。对特征参数的维护由系统内部(游戏程序)一个叫做发起人的对象解析并维护的,发起人是系统内部对象,记录系统每一个时刻的特征值,并能将特征值以备忘录的形式进行存储,而且可以读取外部的备忘录,将特征参数付给系统,达到恢复的目的。那么游戏的备份与恢复,由发起者(游戏内部的一个管理特征状态的类)、备忘录(特征状态的数据载体)和管理者(完成备忘录数据的存储)三个类组成。
备忘录是一个数据对象(类似pojo)只做数据的表示,管理者仅完成备忘录得存取,发起人完成数据备忘录对象的状态备份与状态恢复,记录某一个时刻的游戏特征参数,如:体力、战斗力等,或者将将这些特征参数用原有备忘录中数据进行覆盖恢复。这样遵循单一职责原则,使得各个部分的功能单一,更易于维护。
代码
以下通过游戏记录角色的体力、战斗力和防御力例子,分析备忘录模式代码
首先建立备忘录记录各种状态,它只是数据的载体,仅包含get、set方法,代码如下:
public class RoleStateMemento {
private int vitality;
private int attack;
private int defense;
public RoleStateMemento(int vitality, int attack, int defense) {
this.vitality = vitality;
this.attack = attack;
this.defense = defense;
}
public int getVitality() {
return vitality;
}
public void setVitality(int vitality) {
this.vitality = vitality;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
}
在游戏内部,有一个用于记录当前游戏状态的管理类,该类与游戏系统耦合,即备忘录模式中的发起人,它用来操作将游戏中人物的当前状态记录到备忘录vo中,同时也可以将传入的备忘录数据载体中的数据赋给游戏中人物,起到恢复的作用,本部分代码如下:
public class GameRole {
//生命力
private int vitality;
//攻击力
private int attack;
//防御力
private int defense;
public int getVitality() {
return vitality;
}
public void setVitality(int vitality) {
this.vitality = vitality;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public void setDefense(int defense) {
this.defense = defense;
}
public int getDefense() {
return defense;
}
//获得初始状态
public void getInitState() {
this.vitality=100;
this.attack=100;
this.defense=100;
}
//战斗
public void fight() {
this.vitality=vitality-10;
this.attack=attack-20;
this.defense=defense-10;
}
//保存当前状态
public RoleStateMemento saveState() {
return new RoleStateMemento(vitality,attack,defense);
}
//恢复状态
public void recoverState(RoleStateMemento memento) {
this.vitality=memento.getVitality();
this.attack=memento.getAttack();
this.defense=memento.getDefense();
}
}
单独分出一个对象,用于管理备忘录的存储、检索等,即管理者角色,代码如下
public class Caretaker {
private RoleStateMemento memento;
/**
* 备忘录的取值方法
*/
public RoleStateMemento retrieveMemento(){
return this.memento;
}
/**
* 备忘录的赋值方法
*/
public void saveMemento(RoleStateMemento memento){
this.memento = memento;
}
}
备忘录模式与原型模式区别
原型模式是复制一个完整的对象,而备忘录模式仅复制系统的特征参数。
启发
通过备忘录模式,可以启发我们在设计时,需要根据单一职责原则,将系统涉及的对象进行细分。