備忘錄模式提供一種狀態恢復的實現機制, 用戶能夠方便的回到一個特定的歷史步驟, 當新的狀態無效或者存在問題時候, 可使用暫時存起來的備忘錄將狀態復原, 當前不少軟件中提供的撤銷操做, 其中使用了備忘錄模式.數據庫
備忘錄模式: 在不破壞封裝的前提下, 捕獲一個對象的內部狀態, 並在該對象以外保存這個狀態, 這樣能夠在之後將狀態恢復到原先保存的狀態. 它是一種對象行爲模式.編程
備忘錄模式的核心是備忘錄類以及用於管理備忘錄的負責人類的設計, 其結構以下所示:瀏覽器
備忘錄模式關鍵在於如何設計備忘錄類和負責人類. 因爲在備忘錄中存儲的是原發器的中間狀態, 所以須要防止原發器之外的其它對象訪問備忘錄, 特別是不容許其它對象來修改備忘錄.app
備忘錄模式, Swift版本客戶端代碼:編程語言
備忘錄模式代碼:.net
// ChessMan class ChessMan: NSObject { var label: String? var x: Int? var y: Int? // 初始化棋子狀態 init(label: String, x: Int, y: Int) { self.label = label self.x = x self.y = y } // 移動棋子 func move(x: Int, y: Int) { self.x = x self.y = y } // 保存狀態, 返回當前對象狀態的類, 即備忘錄 func save() -> ChessmanMemento { return ChessmanMemento(chessman: self) } // 恢復到一個歷史狀態, 參數是一個狀態 func restore(memento: ChessmanMemento) { label = memento.label x = memento.x y = memento.y } } // ChessmanMemento class ChessmanMemento: NSObject { var label: String var x: Int var y: Int init(chessman: ChessMan) { label = chessman.label ?? "" x = chessman.x ?? 0 y = chessman.y ?? 0 } } // MementoCaretaker class MementoCaretaker: NSObject { lazy var mementoArray = [ChessmanMemento]() // 根據歷史狀態, 從狀態列表中獲取一個歷史狀態 func getMemento(index: Int) -> ChessmanMemento { return mementoArray.remove(at: index) } // 獲取最近的狀態 func getLatestMemento() -> ChessmanMemento { return mementoArray.removeLast() } // 獲取最老的的狀態 func getOldestMemento() -> ChessmanMemento { return mementoArray.removeFirst() } // 添加一個狀態 func addMemento(memento: ChessmanMemento) { mementoArray.append(memento) } }
備忘錄是一個很特殊的對象,只有原發器對它擁有控制的權力,負責人只負責管理,而其餘類沒法訪問到備忘錄,所以咱們須要對備忘錄進行封裝。設計
爲了實現對備忘錄對象的封裝,須要對備忘錄的調用進行控制,對於原發器而言,它能夠調用備忘錄的全部信息,容許原發器訪問返回到先前狀態所需的全部數據;對於負責人而言,只負責備忘錄的保存並將備忘錄傳遞給其餘對象;對於其餘對象而言,只須要從負責人處取出備忘錄對象並將原發器對象的狀態恢復,而無須關心備忘錄的保存細節。理想的狀況是隻容許生成該備忘錄的那個原發器訪問備忘錄的內部狀態。rest
在實際開發中,原發器與備忘錄之間的關係是很是特殊的,它們要分享信息而不讓其餘類知道,實現的方法因編程語言的不一樣而有所差別,在C++中可使用friend關鍵字,讓原發器類和備忘錄類成爲友元類,互相之間能夠訪問對象的一些私有的屬性;在Java語言中能夠將原發器類和備忘錄類放在一個包中,讓它們之間知足默認的包內可見性,也能夠將備忘錄類做爲原發器類的內部類,使得只有原發器才能夠訪問備忘錄中的數據,其餘對象都沒法使用備忘錄中的數據。code
備忘錄模式在不少軟件的使用過程當中廣泛存在,可是在應用軟件開發中,它的使用頻率並不過高,由於如今不少基於窗體和瀏覽器的應用軟件並無提供撤銷操做。若是須要爲軟件提供撤銷功能,備忘錄模式無疑是一種很好的解決方案。在一些字處理軟件、圖像編輯軟件、數據庫管理系統等軟件中備忘錄模式都獲得了很好的應用。對象
資源消耗過大,若是須要保存的原發器類的成員變量太多,就不可避免須要佔用大量的存儲空間,每保存一次對象的狀態都須要消耗必定的系統資源。
Reference: http://blog.csdn.net/lovelion/article/details/7526747