Gof設計模式之備忘錄模式 (Memento)

備忘錄模式定義:備忘錄是一個對象,它保存另外一個對象在某一時刻的狀態。

備忘錄模式功能:在不破壞對象的封裝性的前提下,保存對象的某一時刻的內部狀態。
不破壞封裝性,即不暴露對象沒必要要的細節。

備忘錄模式中涉及的名詞與解釋。
一、備忘錄
備忘錄,它是一個封裝數據的對象,它保存某一對象的某個時刻的狀態,它不一樣於普通的封裝數據的對象,它不該包含多於的細節(方法)。
爲了實現對象的封裝性,一般備忘錄的實現代碼放到原發器類中,做爲原發器類的內部私有類,只經過原發器對其操做;
二、原發器
原發器,它是咱們要用備忘錄去保存狀態的對象。經過它來操做備忘錄,建立和恢復它的某一時刻的備忘錄。
三、備忘錄管理器
用於緩存備忘錄,而且能夠緩存多個。

備忘錄模式的優缺點
一、優勢:
  (1)更好的封裝性
     經過備忘錄對象保存原發器對象的內部狀態,雖然備忘錄對象保存在管理器中(外部),但因爲經過窄接口的方式實現的備忘錄,導致外部對象沒法操做原發器對象的內部數據。
  (2)簡化了原發器
     備忘錄對象被保存在原發器對象外,由客戶來管理他們請求的狀態,從而簡化了原發器對象。
  (3)窄接口與寬接口
     窄接口與寬接口實現了原發器對象在不一樣的地方有不一樣的訪問方式。原發器外部經過窄接口訪問備忘錄,保護原發器對象的狀態。
     在原發器內部,能夠經過寬接口設置備忘錄,保存某一時刻的備忘錄。
二、缺點
  能夠會致使高開銷。
  備忘錄的基本功能,就是建立、恢復備忘錄中的狀態,備忘錄的基本實現方式就是緩存備忘錄對象。
  若是高頻率的建立備忘錄,或是備忘錄中緩存的數據量較大,都會致使高開銷。

示例:
示例說明:一個對象初始化後,通過初步處理獲得某一狀態,用備忘錄保存此狀態。再用不一樣的處理,處理此狀態。
代碼:
一、備忘錄的窄接口
public class Memeto{
}

二、備忘錄的原發器(備忘錄爲某一對象保存某一狀態,這個對象就是原發器)。
package gof.memeto;

/**
 * @author andy
 * 備忘錄的原發器
 */
public class Originator {
 // 原發器名稱
 private String name;
 // 原發器某一狀態時的值
 private String state;
 // 原發器某一狀態時的值
 private String result;

 public Originator(String n) {
 this.name = n;
 }

 /**
  * 初始化原發器,獲得要保存的狀態
  */
 public void runInit() {
 this.state = "state0";
 this.result = "result0";
 }

 /**
  * 方案1改變保存的狀態
  */
 public void runSchema1() {
 this.state += "----state1";
 this.result += "----result1";
 System.out.println("state:" + this.state);
 System.out.println("result:" + this.result);
 }

 /**
  * 方案2改變保存的狀態
  */
 public void runSchema2() {
 this.state += "----state2";
 this.result += "----result2";
 System.out.println("state:" + this.state);
 System.out.println("result:" + this.result);
 }

 public Memeto createMemeto() {
 return new MemetoImpl(this.state, this.result);
 }

 public void setMemeto(Memeto m) {
 MemetoImpl mi = (MemetoImpl) m;
 this.state = mi.state;
 this.result = mi.result;
 }

 private static class MemetoImpl implements Memeto {
 // 保存原發器某一狀態時的值
 private String state;
 // 保存原發器某一狀態時的值
 private String result;

 public MemetoImpl(String s, String r) {
 this.state = s;
 this.result = r;
 }

 /**
  * @return the state
  */
 public String getState() {
 return state;
 }

 /**
  * @return the result
  */
 public String getResult() {
 return result;
 }

 }
}

三、備忘錄的管理者
package gof.memeto;

/**
 * @author andy
 * 備忘錄的管理者
 */
public class MemetoCareTaker {
 private Memeto memeto = null;

 public void savaMemeto(Memeto memeto) {
 this.memeto = memeto;
 }

 public Memeto retriveMemeto() {
 return memeto;
 }

}

四、測試Main方法
package gof.memeto;

public class Main {

 /**
  * @param args
  */
 public static void main(String[] args) {
 // 原發器
 Originator ori = new Originator("memeto test");
 // 初始化原發器
 ori.runInit();
 
 // 備忘錄的管理者
 MemetoCareTaker mct = new MemetoCareTaker();
 mct.savaMemeto(ori.createMemeto());
 
 // 運行方案1
 ori.runSchema1();
 
 // 不用備忘錄恢復狀態,運行方案2
 ori.runSchema2();
 
 // 用備忘錄恢復狀態,運行方案2
 ori.setMemeto(mct.retriveMemeto());
 ori.runSchema2();
 }

}
相關文章
相關標籤/搜索