天天看點

備忘錄模式(Memento Pattern)遊戲角色狀态恢複問題傳統方案解決遊戲角色恢複傳統的方式的問題分析備忘錄模式基本介紹備忘錄模式的原理類圖遊戲角色恢複狀态執行個體備忘錄模式的注意事項和細節總結

遊戲角色狀态恢複問題

遊戲角色有攻擊力和防禦力,在大戰Boss 前儲存自身的狀态(攻擊力和防禦力),當大戰Boss 後攻擊力和防禦力下降,從備忘錄對象恢複到大戰前的狀态

傳統方案解決遊戲角色恢複

備忘錄模式(Memento Pattern)遊戲角色狀态恢複問題傳統方案解決遊戲角色恢複傳統的方式的問題分析備忘錄模式基本介紹備忘錄模式的原理類圖遊戲角色恢複狀态執行個體備忘錄模式的注意事項和細節總結

傳統的方式的問題分析

  1. 一個對象,就對應一個儲存對象狀态的對象, 這樣當我們遊戲的對象很多時,不利于管理,開銷也很大.
  2. 傳統的方式是簡單地做備份,new 出另外一個對象出來,再把需要備份的資料放到這個新對象,但這就暴露了對象内部的細節
  3. 解決方案: => 備忘錄模式

備忘錄模式基本介紹

基本介紹

  1. 備忘錄模式(Memento Pattern)在不破壞封裝性的前提下,捕獲一個對象的内部狀态,并在該對象之外儲存這個狀态。這樣以後就可将該對象恢複到原先儲存的狀态
  2. 可以這裡了解備忘錄模式:現實生活中的備忘錄是用來記錄某些要去做的事情,或者是記錄已經達成的共同意見的事情,以防忘記了。而在軟體層面,備忘錄模式有着相同的含義,備忘錄對象主要用來記錄一個對象的某種狀态,或者某些資料,當要做回退時,可以從備忘錄對象裡擷取原來的資料進行恢複操作
  3. 備忘錄模式屬于行為型模式

備忘錄模式的原理類圖

備忘錄模式(Memento Pattern)遊戲角色狀态恢複問題傳統方案解決遊戲角色恢複傳統的方式的問題分析備忘錄模式基本介紹備忘錄模式的原理類圖遊戲角色恢複狀态執行個體備忘錄模式的注意事項和細節總結
  • 對原理類圖的說明-即(備忘錄模式的角色及職責)
  1. originator : 對象(需要儲存狀态的對象)
  2. Memento : 備忘錄對象,負責儲存好記錄,即Originator 内部狀态
  3. Caretaker: 守護者對象,負責儲存多個備忘錄對象, 使用集合管理,提高效率
  4. 說明:如果希望儲存多個originator 對象的不同時間的狀态,也可以,隻需要要HashMap <String, 集合>

儲存:需要儲存狀态的對象建立備忘錄對象,再把備忘錄對象儲存到守護者對象,

讀取,從守護者對象讀取備忘錄對象,錄入需要儲存狀态的對象

 代碼實作

遊戲角色恢複狀态執行個體

  1. 應用執行個體要求

    遊戲角色有攻擊力和防禦力,在大戰Boss 前儲存自身的狀态(攻擊力和防禦力),當大戰Boss 後攻擊力和防禦力下降,從備忘錄對象恢複到大戰前的狀态

  2. 思路分析和圖解(類圖)
    備忘錄模式(Memento Pattern)遊戲角色狀态恢複問題傳統方案解決遊戲角色恢複傳統的方式的問題分析備忘錄模式基本介紹備忘錄模式的原理類圖遊戲角色恢複狀态執行個體備忘錄模式的注意事項和細節總結
    Gamerole裡面有Memeto
  3. 代碼實作

用戶端

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//建立遊戲角色
		GameRole gameRole = new GameRole();
		gameRole.setVit(100);
		gameRole.setDef(100);
		
		System.out.println("和boss大戰前的狀态");
		gameRole.display();
		
		//把目前狀态儲存caretaker
		Caretaker caretaker = new Caretaker();
		caretaker.setMemento(gameRole.createMemento());
		
		System.out.println("和boss大戰~~~");
		gameRole.setDef(30);
		gameRole.setVit(30);
		
		gameRole.display();
		
		System.out.println("大戰後,使用備忘錄對象恢複到站前");
		
		gameRole.recoverGameRoleFromMemento(caretaker.getMemento());
		System.out.println("恢複後的狀态");
		gameRole.display();
	}

}
           

需要儲存狀态的對象:

public class GameRole {

	private int vit;
	private int def;
	
	//建立Memento ,即根據目前的狀态得到Memento
	public Memento createMemento() {
		return new Memento(vit, def);
	}
	
	//從備忘錄對象,恢複GameRole的狀态
	public void recoverGameRoleFromMemento(Memento memento) {
		this.vit = memento.getVit();
		this.def = memento.getDef();
	}
	
	//顯示目前遊戲角色的狀态
	public void display() {
		System.out.println("遊戲角色目前的攻擊力:" + this.vit + " 防禦力: " + this.def);
	}

	public int getVit() {
		return vit;
	}

	public void setVit(int vit) {
		this.vit = vit;
	}

	public int getDef() {
		return def;
	}

	public void setDef(int def) {
		this.def = def;
	}
		
}
           

備忘錄對象,負責儲存好記錄

public class Memento {

	//攻擊力
	private int vit;
	//防禦力
	private int def;
	public Memento(int vit, int def) {
		super();
		this.vit = vit;
		this.def = def;
	}
	public int getVit() {
		return vit;
	}
	public void setVit(int vit) {
		this.vit = vit;
	}
	public int getDef() {
		return def;
	}
	public void setDef(int def) {
		this.def = def;
	}
	
}
           

守護者對象,負責儲存多個備忘錄對象

import java.util.ArrayList;
import java.util.HashMap;

//守護者對象, 儲存遊戲角色的狀态
public class Caretaker {

	//如果隻儲存一次狀态
	private Memento  memento;
	//對GameRole 儲存多次狀态
	//private ArrayList<Memento> mementos;
	//對多個遊戲角色儲存多個狀态
	//private HashMap<String, ArrayList<Memento>> rolesMementos;

	public Memento getMemento() {
		return memento;
	}

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

備忘錄模式的注意事項和細節

  1. 給使用者提供了一種可以恢複狀态的機制,可以使使用者能夠比較友善地回到某個曆史的狀态
  2. 實作了資訊的封裝,使得使用者不需要關心狀态的儲存細節
  3. 如果類的成員變量過多,勢必會占用比較大的資源,而且每一次儲存都會消耗一定的記憶體, 這個需要注意
  4. 适用的應用場景:1、後悔藥。2、打遊戲時的存檔。3、Windows 裡的ctri + z。4、IE 中的後退。4、資料庫的事務管理
  5. 為了節約記憶體,備忘錄模式可以和原型模式配合使用

總結

看 備忘錄模式的原理類圖

繼續閱讀