备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象外保存这个状态,这样以后可将此对象恢复成原来的状态。
就拿单机游戏举例,玩游戏打boss前我们通常都会存档,避免打boss时失误死亡好恢复存档重新开始,我们首先看下面的例子。
//游戏鬼泣的主角Dante类
public classDante {//生命值
private inthealth;//魔法值
private intmana;public intgetHealth() {returnhealth;
}public void setHealth(inthealth) {this.health =health;
}public intgetMana() {returnmana;
}public void setMana(intmana) {this.mana =mana;
}//角色的初始状态
public voidgetInitState(){this.health = 100;this.mana = 100;
}public voiddeathState(){this.health = 0;this.mana = 0;
}public voidshowState(){
System.out.println("health:"+health+",mana:"+mana);
}
}
public classTest {public static voidmain(String[] args) {//初始化状态
Dante dante = newDante();
dante.getInitState();
dante.showState();//存档
Dante danteBak = newDante();
danteBak.setHealth(dante.getHealth());
danteBak.setMana(dante.getMana());//角色死亡时的状态
dante.deathState();
dante.showState();//恢复存档
dante.setHealth(danteBak.getHealth());
dante.setMana(danteBak.getMana());
dante.showState();
}
}
测试结果:
health:100,mana:100
health:0,mana:0
health:100,mana:100
上面的方法虽然实现了存档,可是实现的并不优美,在测试方法中暴露了太多存档的实现细节,并且如果以后需要保存新的角色属性,那我们就需要修改客户端,所以我们就用到了备忘录模式,把角色属性的保存封装在单独的类中,体现“职责分离”。示例如下。
首先定义了一个“存储卡”类,用于保存角色数据
public classMemoryCard {private inthealth;private intmana;public intgetHealth() {returnhealth;
}public void setHealth(inthealth) {this.health =health;
}public intgetMana() {returnmana;
}public void setMana(intmana) {this.mana =mana;
}public MemoryCard(int health,intmana){this.health =health;this.mana =mana;
}
}
角色状态管理者,用于保存存储卡,并且不能对存储卡的内容进行操作
public classMemoryCardCreataker {privateMemoryCard memoryCard;publicMemoryCard getMemoryCard() {returnmemoryCard;
}public voidsetMemoryCard(MemoryCard memoryCard) {this.memoryCard =memoryCard;
}
}
游戏角色类
//游戏鬼泣的主角Dante类
public classDante {//生命值
private inthealth;//魔法值
private intmana;public intgetHealth() {returnhealth;
}public void setHealth(inthealth) {this.health =health;
}public intgetMana() {returnmana;
}public void setMana(intmana) {this.mana =mana;
}//角色的初始状态
public voidgetInitState(){this.health = 100;this.mana = 100;
}public voiddeathState(){this.health = 0;this.mana = 0;
}public voidshowState(){
System.out.println("health:"+health+",mana:"+mana);
}//将角色状态保存在存储卡中
publicMemoryCard saveState(){return newMemoryCard(health,mana);
}//回档
public voidrecoveryState(MemoryCard memoryCard){this.health =memoryCard.getHealth();this.mana =memoryCard.getMana();
}
}
测试方法
public classTest {public static voidmain(String[] args) {//初始化状态
Dante dante = newDante();
dante.getInitState();
dante.showState();//存档
MemoryCardCreataker memoryCardCreataker = newMemoryCardCreataker();
memoryCardCreataker.setMemoryCard(dante.saveState());//角色死亡时的状态
dante.deathState();
dante.showState();//恢复存档
dante.recoveryState(memoryCardCreataker.getMemoryCard());
dante.showState();
}
}
测试结果:
health:100,mana:100
health:0,mana:0
health:100,mana:100
总结 优点:使用备忘录模式很好地将被保存的对象和保存的状态分隔开来,并且该对象状态备份和恢复不需要自己处理,而是转交给客户端处理,并且如何保存的细节封装到了存储卡中,不再影响客户端。
缺点:由于备忘录对象会消耗内存,如果需要保存的状态占用的内存较大时,资源的消耗也就越大。