从王者荣耀看设计模式
一.简介
点击王者荣耀商店法术的装备栏,存在有"贤者的庇护"这一装备。在对战中,当玩家处于死亡状态时,会触发此装备的效果,能够让英雄重新复活。
┬┴┬┌─ ●─┬─ │─┼─┐ ●├─┤○
┴┬┴├┬ ┌─┼─ │◎ │ │ ○└┬┘●
─┼─││ │ │ ││─┴─┴ ──┼──
●│○││ ┴─┼─ │○ ● / │ \
二.模式动机
在应用软件的开发中,很多时候我们都需要记录一个对象的内部状态。在具体实现时,为了允许用户取消不确定的操作或从错误中恢复过来,需要设置备份点并提供撤销机制,而要实现这些机制,必须事先将状态信息保存在某处,这样才能将对象恢复到它们原先的状态。备忘录模式是一种给我们的软件提供后悔药的机制,通过它可以使系统恢复到某一特定的历史状态。在本实例中,装备提供备份的功能,将英雄死亡之前的状态备份,英雄死亡触发备份事件将备份状态取出
三.备忘录模式
备忘录模式(Memento Pattern):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是种对象行为型模式
备忘录模式的应用场景
在以下情况下可以使用备忘录模式
■ 保存一个对象在某一个时刻的状态或部分状态,这样以后需要时它能够恢复到先前的状态
■ 如果用一个接口来让其他对象得到这些状态,将会暴露对象的实现细节并破坏对象的封装性,一个对象不希望外界直接访问其内部状态,通过负责人可以间接访问其内部状态
备忘录模式的通用类图
备忘录模式涉及的角色
备忘录模式包含以下角色
⑴.Originator(原发器):原发器可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态,一般需要保存内部状态的类设计为原发器,如一个存储用户信息或商品信息的对象
⑵.Memento(备忘录):存储原发器的内部状态,根据原发器来决定保存哪些内部状态。备忘录的设计一般可以参照原发器的设计,根据实际需要来确定备忘录中的属性,需要注意的是,除了原发器本身与负责人类之外,备忘录对象不能直接供其他类使用
⑶. Caretaker(负责人)
负责人又称为管理者,它负责保存备忘录,但是不能对备忘录的内容进行操作或检查,在负责人对象中可以存储一个或多个对象,它只负责存储对象,而不能修改对象,也无法知道对象的具体实现细节
备忘录模式优点:
⑴.提供一种状态恢复的实现机制
⑵.实现了信息的封装,使用堆栈来存储备忘录对象可以实现多次撤销操作
备忘录模式缺点:
资源消耗大,每保存一次状态都要耗费内存资源
四.结构图
五.代码实现
Originator类
package com.practice.memento;
/*
* 创建原发器类,存储当前的内部状态
*/
public class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
//创建备忘录,存储当前状态
public Memento createMemento() {
return new Memento(state);
}
//将存储的状态从备忘录中取出
public void restoreMemento(Memento m) {
this.setState(m.getState());
}
}
Memento类
package com.practice.memento;
/*
* 创建备忘录类,存储原发器的内部状态
*/
public class Memento {
private String state;
//接收原发器的内部状态
public Memento(String state) {
this.state = state;
}
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
Caretaker类
package com.practice.memento;
/*
* 创建负责人类,负责保存备忘录,存储备忘录对象
*/
public class Caretaker {
private Memento memento;
public void setMemento(Memento m) {
memento = m;
}
public Memento getMemento() {
return memento;
}
}
Client类
package com.practice.memento;
public class Client {
public static void main(String[] args) {
//创建原发器对象
Originator or = new Originator();
//创建负责人对象
Caretaker cr = new Caretaker();
//设置原发器当前状态
or.setState("You are still alive!");
System.out.println("初始状态:" + or.getState());
//将原发器当前状态存入备忘录中
cr.setMemento(or.createMemento());
//设置原发器新状态
or.setState("You have been slained!");
System.out.println("新的状态" + or.getState());
//将初始状态从备忘录中取出
or.restoreMemento(cr.getMemento());
System.out.println("恢复状态:" + or.getState());
}
}
运行结果: