1.意圖
在不破壞封裝性的前提下暮胧,捕獲一個對象的內(nèi)部狀態(tài)胜臊,并在該對象之外保存這個狀態(tài)吞加,這樣以后就可以將該對象恢復到先前保存的狀態(tài)裙犹。
2.結構和代碼
組織者尽狠,把原發(fā)器的狀態(tài)State(全部或者部分狀態(tài),一般是變量的值)叶圃,通過CreateMemento()方法保存起來袄膏,繼續(xù)運行后,等待合適的時機掺冠,在通過SetMemento()方法可以再次恢復到之前的狀態(tài)沉馆。在這個過程中,我們并沒有對這些狀態(tài)做任何的訪問和設置德崭,實際上這些狀態(tài)都是私有的斥黑,對外是禁止訪問的,我們只是通過Memento對象的兩個最簡單的方法就達到了這個效果眉厨。Memento經(jīng)常寫成Originator的內(nèi)部類锌奴。
在Android中,Canvas有兩個方法 save()和restore()方法再做圖形變換的時候使用的非常多憾股,因為涉及到跨語言的問題鹿蜀,我不好就認定這個用的是備忘錄模式,但是它的這種思想絕對是備忘錄的思想服球。
我們來讀一讀它源代碼的注釋吧茴恰,首先看save()保存狀態(tài):
public class Canvas {
/**
* Saves the current matrix and clip onto a private stack. Subsequent
* calls to translate,scale,rotate,skew,concat or clip Rect,clipPath
* will all operate as usual, but when the balancing call to restore()
* is made, those calls will be forgotten, and the settings that existed
* before the save() will be reinstated.
*/
/**
*保存當前的矩陣和剪裁到一個私有的堆棧,其實矩陣和剪裁就是當前Canvas的狀態(tài)State
*/
public native int save();
}
再看恢復狀態(tài)restore():
public class Canvas {
/**
* This call balances a previous call to save(), and is used to remove all
* modifications to the matrix/clip state since the last save call. It is
* an error to call restore() more times than save() was called.
*/
/**
* 移除自上次保存操作后所做的修改有咨,恢復到之前的狀態(tài)琐簇,因為是堆棧實現(xiàn),所以pull操作不能不等于push操作座享,save()和restore()應該成對使用婉商,否則恢復的狀態(tài)就很有可能是錯誤的
*/
public native void restore();
}
從上面的兩個方法中,它們實現(xiàn)了自我狀態(tài)的恢復渣叛,實際上我們只是執(zhí)行了兩個沒有接觸任何內(nèi)部信息的方法丈秩,實際上這兩個方法就是在操作我們看不到的這些內(nèi)部狀態(tài)信息。
3.效果
(1).保持封裝邊界淳衙,把很復雜的原發(fā)器的內(nèi)部信息對外部其他對象隱藏起來蘑秽。
(2).簡化的原發(fā)器,把狀態(tài)操作無形中轉(zhuǎn)化到客戶手里箫攀,簡化了原發(fā)器的某些實現(xiàn)肠牲。
(3).也要注意注意備忘錄的管理代價。