设计模式-备忘录模式(Memento)以及JDK类库中的应用

备忘录模式

定义

在不破坏封装性的前提下,捕获一个对象的状态,并在此对象的外部保存这个对象的状态,这样在以后就可以恢复到原先保存的状态。

结构

Originator(发起人):它是需要保存的状态值的原始对象,状态值可以有多个也可以只有一个,它负责创建备忘录类并将需要保存的状态值保存在这个类中,它还可以恢复备忘录类中保存的状态值。

Memento(备忘录):负责保存状态值,和一个由状态值作为参数的构造器。

CareTaker(备忘录管理类):负责保存Memento。

类图

设计模式-备忘录模式(Memento)以及JDK类库中的应用_第1张图片

Originator:

public class Originator {

	private String state;//需要保存的状态值
	
	/**
	 * 	创建备忘录类,将需要保存的状态值保存在新建的Memo中
	 */
	public Memento createMeme(){
		return new Memento(state);
	}
	
	/**
	 *	恢复备忘录
	 */
	public void setMeme(Memento meme){
		this.state = meme.getState();
	}
	
	public void display(){
		System.out.println("当前状态值:"+state);
	}

	public void setState(String state) {
		this.state = state;
	}
	
}

Memento:

public class Memento {

	private String state;//需要保存的状态值
	
	/**
	 * 	保存状态值的构造器
	 */
	public Memento(String state){
		this.state = state;
	}
	
	public String getState() {
		return state;
	}
	
}

CareTaker:

public class CareTaker {
	
	private Memento memento;

	public Memento getMemento() {
		return memento;
	}

	public void setMemento(Memento memento) {
		this.memento = memento;
	}

}

测试类:

	public static void main(String[] args) {
		Originator originator = new Originator();
		originator.setState("on");
		Memento createMeme = originator.createMeme();//创建备忘录类
		CareTaker taker = new CareTaker();
		taker.setMemento(createMeme);
		originator.setState("off");//状态值发生改变
		originator.display();
		originator.setMeme(taker.getMemento());
		originator.display();
	}

结果:

案例

相信很多人都玩过单机游戏,那么当我们打到boss的时候,如何在失败的情况下重新开始挑战boss呢,这里就用到存档,那么存档功能是如何实现的呢?

其实存档就可以用备忘录模式来实现:

游戏玩家:

public class GameRole {

	//需要保存的状态值
	private int HP;
	private int attack;
	private int defense;
	
	//创建备忘录类
	public RoleMemento createMemento(){
		return new RoleMemento(HP,attack,defense);
	}
	
	//恢复备忘录类
	public void setMemento(RoleMemento memento){
		this.HP = memento.getHP();
		this.attack = memento.getAttack();
		this.defense = memento.getDefense();
	}
	
	public void display(){
		System.out.println("角色当前状态:血量"+ HP +",攻击力"+ attack +",防御力"+defense);
	}
	public int getHP() {
		return HP;
	}
	public void setHP(int hP) {
		HP = hP;
	}
	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 class RoleMemento {

	//需要保存的状态值
	private int HP;
	private int attack;
	private int defense;
	
	public RoleMemento(int HP, int attack,int defense){
		this.HP = HP;
		this.attack = attack;
		this.defense = defense;
	}
	public int getHP() {
		return HP;
	}
	public int getAttack() {
		return attack;
	}
	public int getDefense() {
		return defense;
	}
	
}

备忘录管理类:

public class RoleCareTaker {

	private RoleMemento memento;
	
	public RoleMemento getMemento() {
		return memento;
	}
	
	public void setMemento(RoleMemento memento) {
		this.memento = memento;
	}

}

测试类:

	public static void main(String[] args) {
		GameRole gameRole = new GameRole();
		gameRole.setHP(100);
		gameRole.setAttack(100);
		gameRole.setDefense(100);
		//存档
		RoleMemento memento = gameRole.createMemento();
		//保存在备忘录管理类中
		RoleCareTaker taker = new RoleCareTaker();
		taker.setMemento(memento);
		//和boss决斗失败
		gameRole.setHP(0);
		gameRole.setAttack(0);
		gameRole.setDefense(0);
		gameRole.display();
		//恢复决斗前状态
		gameRole.setMemento(taker.getMemento());
		gameRole.display();
	}

测试结果:

优点

1.可以使对象恢复到某一时间节点的状态。

2.客户端无需考虑备忘录类的具体细节,实现信息的封装。

缺点

如果备忘录类越来越多,占用内存资源必定会对系统造成重大影响。

JDk类库中的备忘录模式

java.util.Date

Date date = new Date(100);构造器参数将会被缓存到一个long值中。

java.io.Serializable

比如说玩单机游戏有存档功能,该游戏的存档是将数据保存在硬盘中,那就用到Serializable接口,符合备忘录模式。

你可能感兴趣的:(设计模式,设计模式轻松学,备忘录模式)