您的位置:首页 > 编程语言

备忘录模式——编程中的后悔药

2016-02-08 12:12 288 查看
(《设计模式解析与实战——何红辉,关爱民》读书笔记)

一、定义

在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可将该对象恢复到原先保存的状态。

比如,游戏的存档功能;Android中的onSaveInstanceState和onRestoreInstanceState;重做、撤销功能。

二、使用场景

(1)需要保存一个对象在某一时刻的状态或部分状态;

(2)如果用一个接口来让其他对象得到这些状态,将会暴露对象的实现细节并破坏对象的封装性,一个对象不希望外界直接访问其内部状态,通过中间对象可以间接访问其内部状态。

三、简单示例

/**
* 备忘录类:这是一个无状态、无操作的实体类,只负责存储数据,防止外部直接访问内部状态
*/
public class Memorandum {
// 关卡
public int checkPoint;
// 生命值
public int lifeValue;
// 武器
public String weapon;

@Override
public String toString() {
return "Memorandum [checkPoint=" + checkPoint + ", lifeValue=" + lifeValue + ", weapon=" + weapon + "]";
}
}


/**
* 游戏
*/
public class Game {
private int mCheckpoint = 1; // 关卡
private int mLifeValue = 100; // 生命值
private String mWeapon = "沙漠之鹰"; // 武器

/**
* 玩游戏:对关卡和任务的生命值进行修改
*/
public void play() {
System.out.println("打游戏:" + String.format("第%d关", mCheckpoint) + " 奋战杀敌中");
mLifeValue -= 10;
System.out.println("进度升级啦");
mCheckpoint++;
System.out.println("到达:" + String.format("第%d关", mCheckpoint));
}

/**
* 退出游戏
*/
public void quit() {
System.out.println("-------------");
System.out.println("退出前的游戏属性:" + this.toString());
System.out.println("退出游戏");
System.out.println("-------------");
}

/**
* 创建备忘录:将自身的状态保存到备忘录对象中
*/
public Memorandum createMemo() {
Memorandum memorandum = new Memorandum();
memorandum.checkPoint = mCheckpoint;
memorandum.lifeValue = mLifeValue;
memorandum.weapon = mWeapon;
return memorandum;
}

/**
* 恢复游戏:外部将状态从备忘录对象中恢复
*/
public void restore(Memorandum memorandum) {
this.mCheckpoint = memorandum.checkPoint;
this.mLifeValue = memorandum.lifeValue;
this.mWeapon = memorandum.weapon;
System.out.println("恢复后的游戏属性:" + this.toString());
}

public int getmCheckpoint() {
return mCheckpoint;
}

public void setmCheckpoint(int mCheckpoint) {
this.mCheckpoint = mCheckpoint;
}

public int getmLifeValue() {
return mLifeValue;
}

public void setmLifeValue(int mLifeValue) {
this.mLifeValue = mLifeValue;
}

public String getmWeapon() {
return mWeapon;
}

public void setmWeapon(String mWeapon) {
this.mWeapon = mWeapon;
}

@Override
public String toString() {
return "Game [mCheckpoint=" + mCheckpoint + ", mLifeValue=" + mLifeValue + ", mWeapon=" + mWeapon + "]";
}
}


/**
* 负责管理备忘录对象
*/
public class Caretaker {

private Memorandum mMemorandum;

/**
* 存档
*/
public void archive(Memorandum memorandum) {
this.mMemorandum = memorandum;
}

/**
* 获取存档
*
* @return mMemorandum:备忘录对象
*/
public Memorandum getMemorandum() {
return mMemorandum;
}
}


/**
* 客户端
*/
public class Client {
public static void main(String[] args) {

// 构建游戏对象
Game game = new Game();

// 1、打游戏
game.play();

Caretaker caretaker = new Caretaker();

// 2、游戏存档
caretaker.archive(game.createMemo());

// 3、退出游戏
game.quit();

// 4、恢复游戏
Game restoreGame = new Game();
restoreGame.restore(caretaker.getMemorandum());
}
}


运行结果:



四、总结

备忘录模式是在不破坏封装的条件下,通过备忘录对象存储另外一个对象内部状态的快照,在将来合适的时候把这个对象还原到存储起来的状态。

优点:

(1)给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便的回到某个历史状态;

(2)实现了信息的封装,使得用户不需要关心状态的保存细节。

缺点:

消耗资源,如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: