JAVA設計模式之 備忘錄模式【Memento Pattern】

小呂-ICE發表於2014-12-23

一、概述

    在不破壞封裝的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態,這樣就可以在以後將物件恢復至原先儲存的狀態。它是一種物件行為型模式


二、適用場景

    1、類似於撤銷功能的實現,儲存一個物件在某一時間的部分狀態或全部狀態,當以後需要它時就可以恢復至先前的狀態。

    2、 對物件歷史狀態的封裝、避免將物件的歷史狀態的實現細節暴露給外界。


三、UML類圖


四、參與者

    1、Originator(原發器):它是一個普通類,可以建立一個備忘錄,並儲存它的當前內部狀態,也可以使用備忘錄來恢復其內部狀態,一般將需要儲存內部狀態的類設計為原發器。

    2、Memento(備忘錄):儲存原發器的內部狀態,根據原發器來決定儲存哪些內部狀態。備忘錄的設計一般可以參考原發器的設計,根據實際需要確定備忘錄類中的屬性。需要注意的是,除了原發器本身與負責人類之外,備忘錄物件不能直接供其他類使用。

    3、Caretaker(備忘錄管理者或負責人):負責儲存備忘錄,但是不能對備忘錄的內容進行操作或檢查。在該類中可以儲存一個或多個備忘錄物件,它只負責儲存物件,而不能修改物件,也無須知道物件的實現細節。


五、用例學習

    1、備忘錄模式角色之  原發器類:Originator.java

/**
 * 備忘錄模式角色之  原發器<br/>
 * 含有內部需要儲存的狀態屬性
 * @author lvzb.software@qq.com
 *
 */
public class Originator {
	
	private String state;

	/**
	 * 建立一個備忘錄物件 
	 * @return
	 */
	public Memento createMemento(){
		return new Memento(this);
	}
	
	/**
	 * 根據備忘錄物件恢復原發器先前狀態  
	 * @param o
	 */
	public void restoreMemento(Memento o){
		this.state = o.getState();
	}
	
	public String getState() {
		return state;
	}

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

    2、備忘錄模式角色之  備忘錄類:Memento.java

/**
 * 備忘錄模式角色之  備忘錄<br/>
 * 儲存原發器的內部狀態
 * @author lvzb.software@qq.com
 *
 */
public class Memento {

	private String state;

	public Memento(Originator originator) {
		this.state = originator.getState();
	}

	public String getState() {
		return state;
	}

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

    3、備忘錄模式角色之 備忘錄管理者或負責人類:Caretaker.java

/**
 * 備忘錄模式角色之 備忘錄管理者或負責人<br/>
 * 只負責儲存備忘錄物件,而不能修改備忘錄物件,也無須知道備忘錄物件的實現細節<br/>
 * <b>擴充套件:<br/>
 * 如果要實現可以多步撤銷的備忘錄模式 則只需要在此類中使用一個陣列集合來裝載每一步狀態的備忘錄物件 如:<br/>
 *  // 定義一個陣列集合來儲存多個備忘錄物件  <br/>
	List<Memento> mementos = new ArrayList<Memento>();
 * </b>
 * @author lvzb.software@qq.com
 *
 */
public class Caretaker {

	private Memento memento;

	public Memento getMemento() {
		return memento;
	}

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

    4、客戶端測試類Client.java

public class Client {

	public static void main(String[] args) {
		Caretaker caretaker = new Caretaker();
		Originator originator = new Originator();
		// 初始化狀態標識 "0"
		originator.setState("0");
		// 建立狀態為"0"的備忘錄物件
		Memento memento_1 = originator.createMemento();
		// 將記錄了Originator狀態的備忘錄 交給 Caretaker備忘錄管理者儲存
		caretaker.setMemento(memento_1);
		showState(originator);
		
		System.out.println("----- 更改原發器的狀態 -----");
		// 更改原發器的狀態標識為"1"
		originator.setState("1");
		showState(originator);
		
		System.out.println("----- 撤銷至原發器的先前狀態 -----");
		originator.restoreMemento(caretaker.getMemento());
		showState(originator);
	}

	
	private static void showState(Originator originator) {
		System.out.println("Originator 的當前狀態:" + originator.getState());
	}

}

    5、執行結果:

Originator 的當前狀態:0
----- 更改原發器的狀態 -----
Originator 的當前狀態:1
----- 撤銷至原發器的先前狀態 -----
Originator 的當前狀態:0




相關文章