备忘录模式
定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
解决
备忘录模式(Memento),主要用于捕获一个对象的内部状态,以便在将来的某个时候恢复此状态。
优点
- 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
- 实现了信息的封装,使得用户不需要关心状态的保存细节。
缺点
- 消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
结构
备忘录模式包含如下角色:
- Originator: 发起人
- Memento: 备忘录
- Caretaker: 管理者
实现
package mementomethod;
public class Originator {
//相关属性,应该有多个, 是例子就写一个嘛
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
//创建备忘录
public Memento createMemento()
{
return (new Memento(state));
}
//方法():显示数据
public void setMemento(Memento memento)
{
state=memento.getState();
}
public void show()
{
System.out.println("state="+this.state);
}
}
package mementomethod;
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;
}
}
package mementomethod;
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
package mementomethod;
public class MementoClient {
public static void main(String[] args) {
// Originator初始状态,为On
Originator originator = new Originator();
originator.setState("On");
originator.show();
// 管理者通过备忘录保存状态,由于有了很好地封装,可以隐藏Originator的实现细节
Caretaker careTaker = new Caretaker();
careTaker.setMemento(originator.createMemento());
// Originator改变状态,为Off
originator.setState("Off");
originator.show();
// 通过管理者从备忘录中恢复状态
originator.setMemento(careTaker.getMemento());
originator.show();
}
}
实例
package mementomethod.demo;
public class GameRole {
//属性
private int hp;//血条
private int mp;//蓝量
private int atk;//攻击力
private int def;//防御力
//状态显示
public void stateDisplay()
{
System.out.println("角色当前状态:");
System.out.println("HP:"+this.hp);
System.out.println("MP:"+this.mp);
System.out.println("ATK:"+this.atk);
System.out.println("DEF:"+this.def);
}
//获得初始状态
public void getInitState()
{
//数据通常来源于本机磁盘或者远程数据库
this.hp=100;
this.mp=100;
this.atk=100;
this.def=100;
}
//战斗
public void fight()
{
this.hp=0;
this.mp=0;
this.atk=0;
this.def=0;
}
//保存角色状态
public RoleStateMemento saveState()
{
return (new RoleStateMemento(hp,mp,atk,def));
}
//回复角色状态
public void recoveryState(RoleStateMemento memento)
{
this.hp=memento.getHp();
this.mp=memento.getMp();
this.atk=memento.getAtk();
this.def=memento.getDef();
}
//-------------------------------------------
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
public int getMp() {
return mp;
}
public void setMp(int mp) {
this.mp = mp;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk = atk;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
}
package mementomethod.demo;
public class RoleStateMemento {
private int hp;//血条
private int mp;//蓝量
private int atk;//攻击力
private int def;//防御力
//get set
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
public int getMp() {
return mp;
}
public void setMp(int mp) {
this.mp = mp;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk = atk;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
//构造方法,导入数据
public RoleStateMemento(int hp,int mp,int atk,int def)
{
this.hp=hp;
this.mp=mp;
this.atk=atk;
this.def=def;
}
}
package mementomethod.demo;
public class RoleStateCaretaker {
public RoleStateMemento roleStateMemento;
public RoleStateMemento getRoleStateMemento() {
return roleStateMemento;
}
public void setRoleStateMemento(RoleStateMemento roleStateMemento) {
this.roleStateMemento = roleStateMemento;
}
}
package mementomethod.demo;
public class MementoClient {
public static void main(String[] args) {
//大战前
//初始游戏状态,属性都是100
GameRole wanjia =new GameRole();
wanjia.getInitState();
wanjia.stateDisplay();
//保存进度
//现在保存的都是100
RoleStateCaretaker rsc=new RoleStateCaretaker();
rsc.setRoleStateMemento(wanjia.saveState());
//大战boss,死掉了
//死掉了,fight()写的都为0了
wanjia.fight();
wanjia.stateDisplay();
//恢复之前状态
//恢复到上面写的存档
wanjia.recoveryState(rsc.getRoleStateMemento());
wanjia.stateDisplay();
}
}