
5 种创建型模式7 种结构型模式11 种行为型模式状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤定义
快照模式备忘录模式的主要角色如下:
备忘录有两个等效的接口:
【例】游戏挑战BOSS
要实现上述案例,有两种方式:
宽接口
代码如下:
@Data
public class GameRole {
private int vit; //生命力
private int atk; //攻击力
private int def; //防御力
//初始化内部状态
public void initState() {
this.vit = 100;
this.atk = 100;
this.def = 100;
}
//战斗
public void fight() {
this.vit = 0;
this.atk = 0;
this.def = 0;
}
//保存角色状态功能
public RoleStateMemento saveState() {
return new RoleStateMemento(vit,atk,def);
}
//恢复角色状态
public void recoverState(RoleStateMemento roleStateMemento) {
//将备忘录对象中存储的状态赋值给当前对象的成员
this.vit = roleStateMemento.getVit();
this.atk = roleStateMemento.getAtk();
this.def = roleStateMemento.getDef();
}
//展示状态功能
public void stateDisplay() {
System.out.println("角色生命力:" + vit);
System.out.println("角色攻击力:" + atk);
System.out.println("角色防御力:" + def);
}
}@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoleStateMemento {
private int vit; //生命力
private int atk; //攻击力
private int def; //防御力
}public class RoleStateCaretaker {
//声明RoleStateMemento类型的变量
private RoleStateMemento roleStateMemento;
}public class Client {
public static void main(String[] args) {
System.out.println("------------大战Boss前------------");
//大战Boss前
GameRole gameRole = new GameRole();
gameRole.initState();
gameRole.stateDisplay();
//保存进度
RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
roleStateCaretaker.setRoleStateMemento(gameRole.saveState());
System.out.println("------------大战Boss后------------");
//大战Boss时,损耗严重
gameRole.fight();
gameRole.stateDisplay();
System.out.println("------------恢复之前状态------------");
//恢复之前状态
gameRole.recoverState(roleStateCaretaker.getRoleStateMemento());
gameRole.stateDisplay();
}
}
输出结果:
---------------大战boos前-----------------
角色生命力:100
角色攻击力:100
角色防御力:100
---------------大战boos后-----------------
角色生命力:0
角色攻击力:0
角色防御力:0
---------------恢复之前的状态-----------------
角色生命力:100
角色攻击力:100
角色防御力:100RoleStateMemento(状态存储类) 设为 GameRole(游戏角色类) 的内部类,从而将 RoleStateMemento对象封装在GameRole里面Memento 给 RoleStateCaretaker(状态存储管理类) 及其他对象使用GameRole 类看到的是 RoleStateMemento 所有的接口RoleStateCaretaker 及其他对象看到的仅仅是标识接口 Memento 所暴露出来的接口,从而维护了封装型
代码如下:
Memento,这是一个标识接口,因此没有定义出任何的方法public interface Memento {
}GameRole,并在内部定义备忘录内部类 RoleStateMemento(该内部类设置为私有的)@Data
public class GameRole {
private int vit; //生命力
private int atk; //攻击力
private int def; //防御力
//初始化内部状态
public void initState() {
this.vit = 100;
this.atk = 100;
this.def = 100;
}
//战斗
public void fight() {
this.vit = 0;
this.atk = 0;
this.def = 0;
}
//保存角色状态功能
public Memento saveState() {
return new RoleStateMemento(vit, atk, def);
}
//恢复角色状态
public void recoverState(Memento memento) {
RoleStateMemento roleStateMemento = (RoleStateMemento) memento;
//将备忘录对象中存储的状态赋值给当前对象的成员
this.vit = roleStateMemento.getVit();
this.atk = roleStateMemento.getAtk();
this.def = roleStateMemento.getDef();
}
//展示状态功能
public void stateDisplay() {
System.out.println("角色生命力:" + vit);
System.out.println("角色攻击力:" + atk);
System.out.println("角色防御力:" + def);
}
@Data
@NoArgsConstructor
@AllArgsConstructor
private static class RoleStateMemento implements Memento {
private int vit; //生命力
private int atk; //攻击力
private int def; //防御力
}
}RoleStateCaretaker 能够得到的备忘录对象是以 Memento 为接口的@Data
public class RoleStateCaretaker {
//声明RoleStateMemento类型的变量
private Memento memento;
}public class Client {
public static void main(String[] args) {
System.out.println("------------大战Boss前------------");
//大战Boss前
GameRole gameRole = new GameRole();
gameRole.initState();
gameRole.stateDisplay();
//保存进度
RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
roleStateCaretaker.setMemento(gameRole.saveState());
System.out.println("------------大战Boss后------------");
//大战Boss时,损耗严重
gameRole.fight();
gameRole.stateDisplay();
System.out.println("------------恢复之前状态------------");
//恢复之前状态
gameRole.recoverState(roleStateCaretaker.getMemento());
gameRole.stateDisplay();
}
}优点
缺点