文章目录
1. 需求
请用代码实现以下场景:=一个游戏里面的角色有生命力、攻击力、防御力等数据,在打Boss前和后一定会不一样的,我们允许玩家如果感觉与Boss决斗的效果不理想可以让游戏恢复到决斗前。
2. 代码版本1.0
2.1 游戏角色类
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 int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
//状态显示
public void displayState(){
System.out.println("角色当前状态:");
System.out.println("体力:"+this.vitality);
System.out.println("攻击力:"+this.attack);
System.out.println("防御力:"+this.defense);
}
//获取初始状态(数据通常来自本机磁盘或者远程数据接口)
public void getInitState(){
this.vitality=100;
this.attack=100;
this.defense=100;
}
//战斗(跟BOSS战斗后数据损耗成0)
public void fight(){
this.vitality=0;
this.attack=0;
this.defense=0;
}
}
2.2 客户端代码
//大战Boss前
GameRole role = new GameRole();
role.getInitState();
role.displayState();
//保存进度
GameRole backup = new GameRole();
backup.setVitality(role.getVitality());
backup.setAttack(role.getAttack());
backup.setDefense(role.getDefense());
//大战Boss,损耗严重
role.fight();
//显示状态
role.displayState();
//游戏进度回复
role.setVitality(backup.getVitality());
role.setAttack(backup.getAttack());
role.setDefense(backup.getDefense());
//显示状态
role.displayState();
2.3 弊端
游戏角色的细节暴露给客户端,客户端的责任过大。为了解决这个弊端,下面介绍一个模式—备忘录模式
3. 备忘录模式
3.1 概念
备忘录(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
3.2 缺点
角色状态需要完整存储到备忘录对象中,如果状态数据很大很多,那么在资源消耗上,备忘录对象会非常耗内存。
3.3 案例代码
3.3.1 UML类图
3.3.2 发起人(Originator)类
负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator
可根据需要决定Memento存储Originator的哪些内部状态。
public class Originator {
//状态
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
//显示数据
public void show(){
System.out.println("State:"+this.state);
}
//创建备忘录
public Memento createMemento(){
return new Memento(this.state);
}
//恢复备忘录
public void recoveryMemento(Memento memento){
this.setState(memento.getState());
}
}
3.3.3 备忘录(Memento)类
负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。
public class Memento {
private String state;
public Memento(String state){
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
3.3.4 管理者(Caretaker)类
负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。
public class Caretaker {
public Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
3.3.5 客户端代码
//Originator初始状态,属性状态为”On“
Originator o = new Originator();
o.setState("On");
o.show();
Caretaker c = new Caretaker();
//保存状态,由于有了很好的封装,可以隐藏Originator的实现细节
c.setMemento(o.createMemento());
//Originator改变了状态属性为”Off“
o.setState("Off");
o.show();
//恢复原初始状态
o.recoveryMemento(c.getMemento());
o.show();
4. 代码版本2.0(备忘录模式实现)
4.1 UML类图
4.2 游戏角色类
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 int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
//状态显示
public void displayState(){
System.out.println("角色当前状态:");
System.out.println("体力:"+this.vitality);
System.out.println("攻击力:"+this.attack);
System.out.println("防御力:"+this.defense);
}
//获取初始状态(数据通常来自本机磁盘或者远程数据接口)
public void getInitState(){
this.vitality=100;
this.attack=100;
this.defense=100;
}
//战斗(跟BOSS战斗后数据损耗成0)
public void fight(){
this.vitality=0;
this.attack=0;
this.defense=0;
}
//保存角色状态
public RoleStateMemento saveState(){
return new RoleStateMemento(this.vitality,this.attack,this.defense);
}
//回复角色状态
public void recoveryState(RoleStateMemento memento){
this.setVitality(memento.getVitality());
this.setAttack(memento.getAttack());
this.setDefense(memento.getDefense());
}
}
4.3 角色状态存储箱类
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;
}
}
4.4 角色状态管理者类
public class RoleStateCaretaker {
private RoleStateMemento memento;
public RoleStateMemento getMemento() {
return memento;
}
public void setMemento(RoleStateMemento memento) {
this.memento = memento;
}
}
4.5 客户端代码
//大战Boss前
GameRole role = new GameRole();
role.getInitState();
role.displayState();
//保存进度
RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
stateAdmin.setMemento(role.saveState());
//大战BOSS,损耗严重
role.fight();
//显示状态
role.displayState();
//游戏进度恢复
role.recoveryState(stateAdmin.getMemento());
//显示状态
role.displayState();