日拱一卒(三十六)

备忘录模式(Memento):在不破坏封装性的的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的对象。

                                白话:备忘录模式好比游戏中的备份,记录了以前的状态,用于状态出错时恢复使用。

角色:(1)原发器(Originator):需要被备忘存档的对象。

  (2)备忘录(Memento):对原发器中状态备份。

  (3)备份管理器(CareTaker):管理备忘录,本人理解如果存在多个备忘录时有用。

 使用场景:

(1)如果不使用备忘录模式:
游戏角色类GameRole

class GameRole {
	private String name;
	private int force;
	private int life;
	private int defence;

	public GameRole(String name, int force, int life, int defence) {
		super();
		this.name = name;
		this.force = force;
		this.life = life;
		this.defence = defence;
	}

	public boolean attack(int damage) {
		this.life -= damage;
		return this.life > 0;
	}

	private GameRole(GameRole role) {
		this(role.name, role.force, role.life, role.defence);
	}

	public GameRole savaData() {
		GameRole gameRole = new GameRole(this);
		return gameRole;
	}

	public void restoreData(GameRole gameRole) {
		this.name = gameRole.name;
		this.force = gameRole.force;
		this.life = gameRole.life;
		this.defence = gameRole.defence;
	}
使用示例:
public class Game {
	public static void main(String[] args) {
		GameRole role = new GameRole("lixiaoyao", 10, 100, 20);
		GameRole saveRoleData = role.savaData();
		boolean isSuccess = role.attack(100);
		if (!isSuccess) {
		}
		role.restoreData(saveRoleData);
	}
}

可以看到GameRole用自己给自己做备份,这好像可行,但实际过程中我们备份的往往只是部分状态而非所有的,比如GameRole中只需要备份life,因此完全的拷贝GameRole往往造成浪费,因此可以独立一个专门备份的类,用于保存GameRole的部分数据。

(2)使用备忘录类,未使用备忘录管理者

备忘录类:

class RoleMemento {
	private int life;

	public RoleMemento() {
	}

	public int getLife() {
		return life;
	}

	public void setLife(int life) {
		this.life = life;
	}
}

更改后的Game类:

class GameRole {
	private String name;
	private int force;
	private int life;
	private int defence;

	public GameRole(String name, int force, int life, int defence) {
		super();
		this.name = name;
		this.force = force;
		this.life = life;
		this.defence = defence;
	}

	public boolean attack(int damage) {
		this.life -= damage;
		return this.life > 0;
	}


	public RoleMemento savaData() {
		RoleMemento memeto = new RoleMemento();
		memeto.setLife(life);
		return memeto;
	}

	public void restoreData(RoleMemento memento) {
		this.life = memento.getLife();
	}
}

使用示例:

public class Game {
	public static void main(String[] args) {
		GameRole role = new GameRole("lixiaoyao", 10, 100, 20);
		RoleMemento saveRoleData = role.savaData();
		boolean isSuccess = role.attack(100);
		if (!isSuccess) {
			role.restoreData(saveRoleData);
		}
		
	}
}

上面没有用到备忘录管理者,其实这个问题一直很疑惑,原发器只需要跟备忘录交互就行了,备忘录管理者来搅什么局,依照本人所见,如果有多个备份的话,可能就需要用到备份管理者,比如上面我只是备份了角色的生命,但游戏中往往还要备份地图,因此还要增加一个地图备份,而地图备份与角色又应该绑在一起,因此用备忘录管理者可以很好的封装这两个对象。

(3)使用备份管理类的备份录模式:

新的需要备份的类Map和对应备份类MapMemento

class Map {
	private String mapName;
	private int mapProgress;

	public Map(String mapName, int mapProgress) {
		super();
		this.mapName = mapName;
		this.mapProgress = mapProgress;
	}

	public MapMemento savaData() {
		MapMemento memeto = new MapMemento();
		memeto.setMapName(mapName);
		memeto.setMapProgress(mapProgress);
		return memeto;
	}

	public void restoreData(MapMemento memento) {
		this.mapName = memento.getMapName();
		this.mapProgress = memento.getMapProgress();
	}
}
class MapMemento {
	private String mapName;
	private int mapProgress;

	public String getMapName() {
		return mapName;
	}

	public void setMapName(String mapName) {
		this.mapName = mapName;
	}

	public int getMapProgress() {
		return mapProgress;
	}

	public void setMapProgress(int mapProgress) {
		this.mapProgress = mapProgress;
	}

	public MapMemento() {
		super();
	}
}
备份录管理类:

class GameTaker {
	private MapMemento mapMento;
	private RoleMemento roleMento;

	public MapMemento getMapMento() {
		return mapMento;
	}

	public void setMapMento(MapMemento mapMento) {
		this.mapMento = mapMento;
	}

	public RoleMemento getRoleMento() {
		return roleMento;
	}

	public void setRoleMento(RoleMemento roleMento) {
		this.roleMento = roleMento;
	}
}

使用示例:

public class Game {
	public static void main(String[] args) {
		GameRole role = new GameRole("lixiaoyao", 10, 100, 20);
		Map map = new Map("dota6.81", 50);
		GameTaker taker = new GameTaker();
		taker.setRoleMento(role.savaData());
		taker.setMapMento(map.savaData());
		boolean isSuccess = role.attack(100);
		if (!isSuccess) {
			role.restoreData(taker.getRoleMento());
			map.restoreData(taker.getMapMento());;
		}
		
	}
}

注:

  (1)GameTaker保存了两个备份录,GameTaker只存取备份录,并不对其做改变。

    (2)原发器只负责读取,备份的工作交给备份录,简化了原发器的流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值