您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關Android中怎么實現備忘錄模式,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
一、介紹
備忘錄模式是一種行為模式,該模式用于保存對象當前狀態,并且在之后可以再次恢復到此狀態,這有點像我們平時說的”后悔藥“。備忘錄模式實現的方式需要保證被保存的對象狀態不能被對象從外部訪問,目的是為了保護好被保存的這些對象狀態的完整性以及內部實現不向外暴露。
二、定義
在不破壞封閉的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態,這樣,以后就可將該對象恢復到原先保存的狀態。
三、使用場景
需要保存一個對象在某一個時刻的狀態或部分狀態。
如果用一個接口來讓其他對象得到這些狀態,將會暴露對象的實現細節并破壞對象的封裝性,一個對象不希望外界直接訪問其內部狀態,通過中間對象可以間接訪問其內部狀態。
四、備忘錄模式的UML類圖
UML類圖:
角色介紹:
Originator:負責創建一個備忘錄,可以記錄、恢復自身的內部狀態。同時Originator還可以根據需要決定Memento存儲自身的哪些內部狀態。
Memento:備忘錄角色,用于存儲Originator的內部狀態,并且可以防止Originator以外的對象訪問Memento。
Caretaker:負責存儲備忘錄,不能對備忘錄的內容進行操作和訪問,只能將備忘錄傳遞給其他對象。
五、簡單示例
對備忘錄模式來說,比較貼切的場景應該是游戲中的存檔功能,該功能就是將游戲進度存儲到本地文件系統或數據庫中,下次再次進入時從本地加載進度,使得玩家能夠繼續上一次的游戲之旅,這里我們就以”使命召喚“這款游戲為例來簡單演示一下備忘錄模式的實現。
首先我們建立游戲類、備忘錄類、Caretaker類,玩游戲到某個節點對游戲進行存檔,然后退出游戲,再重新進入時從存檔中讀取進行,并且進入存檔時的進度。
游戲類:
/** * * 簡單模擬“使命召喚”游戲 * */ public class CallOfDuty { private int mCheckpoint = 1; private int mLiftValue = 100; private String mWeapon = "沙漠之鷹"; //玩游戲 public void play(){ System.out.println("打游戲:"+String.format("第%d關", mCheckpoint) + "奮戰殺敵中"); mLiftValue -= 10; System.out.println("進度升級了"); mCheckpoint++; System.out.println("到達" + String.format("第%d關", mCheckpoint)); } //退出游戲 public void quit(){ System.out.println("--------------"); System.out.println("退出前的游戲屬性:" + this.toString()); System.out.println("退出游戲"); System.out.println("--------------"); } /** *創建備忘錄 */ public Memento createMemento(){ Memento memento = new Memento(); memento.mCheckpoint = mCheckpoint; memento.mLiftValue = mLiftValue; memento.mWeapon = mWeapon; return memento; } //恢復游戲 public void restore(Memento memento){ this.mCheckpoint = memento.mCheckpoint; this.mLiftValue = memento.mLiftValue; this.mWeapon = memento.mWeapon; System.out.println("恢復后的游戲屬性:" + this.toString()); } //省略getter和setter方法 @Override public String toString() { return "CallOfDuty [mCheckpoint=" + mCheckpoint + ",mLiftValue=" + mLiftValue + ",mWeapon=" + mWeapon + "]"; } }
在CallOfDuty游戲類中,我們存儲了幾個關鍵字段,關卡、人物的生命值、武器,當調用play函數玩游戲時,我們對關卡和人物的生命值進行修改。在該類中可以通過createMemoto函數來創建該用戶的備忘錄對象,也就是將自身的狀態保存到一個Memoto對象中。外部可以通過restore函數將CallOfDuty對象的狀態從備忘錄對象中恢復。
我們在來看下備忘錄對象,它只是存儲CallOfDuty對象的字段,具體代碼如下:
備忘錄類:
/** * 備忘錄類 */ public class Memento { public int mCheckpoint;//武器 public int mLiftValue;//生命 public String mWeapon;//關卡 @Override public String toString() { return "Memento [mCheckpoint=" + mCheckpoint + ",mLiftValue=" + mLiftValue + ",mWeapon=" + mWeapon + "]"; } }
這是一個無狀態、無操作的實體類,只負責用來存儲Originator角色的一些數據,防止外部直接訪問Originator。
而備忘錄的操作者則是Caretaker角色,我們看下相關代碼:
Caretaker類:
/** * Caretaker,負責管理Memento */ public class Caretaker { Memento mMemento; //備忘錄 /** * 存檔 */ public void archive(Memento memento){ this.mMemento = memento; } /** * 獲取存檔 */ public Memento getMemento(){ return mMemento; } }
Caretaker類的職責很簡單,就是負責管理Memoto對象,也就是備忘錄對象。
客戶端類:
public class Client { public static void main(String[] args) { //構建游戲對象 CallOfDuty game = new CallOfDuty(); //1.打游戲 game.play(); Caretaker caretaker = new Caretaker(); //2.游戲存檔 caretaker.archive(game.createMemento()); //3.退出游戲 game.quit(); //4.恢復游戲 CallOfDuty newGame = new CallOfDuty(); newGame.restore(caretaker.getMemento()); } }
結果:
打游戲:第1關奮戰殺敵中 進度升級了 到達第2關 -------------- 退出前的游戲屬性:CallOfDuty [mCheckpoint=2,mLiftValue=90,mWeapon=沙漠之鷹] 退出游戲 -------------- 恢復后的游戲屬性:CallOfDuty [mCheckpoint=2,mLiftValue=90,mWeapon=沙漠之鷹] 打游戲:第2關奮戰殺敵中
上述過程大致有如下4步:
(1)開始游戲,闖關升級;
(2)游戲退出之前進行存檔;
(3)退出游戲;
(4)重新啟動游戲,從存檔中恢復游戲進度。
CallOfDuty在這里為Originator角色,也就是需要存儲數據的對象,在這里并沒有直接存儲CallOfDuty的對象,而是通過Memoto對CallOfDuty對象的數據進行存儲,然后在存儲Memoto對象,最終對Memoto的存取操作則交給Caretaker對象。在這個過程中,各個角色職責清晰、單一,代碼也比較簡單,即對外屏蔽了對CallOfDuty角色的直接訪問,在滿足了對象狀態存取功能的同時也使得該模塊的結構保持清晰、整潔。
六、Android源碼中的備忘錄模式
1、onSaveInstanceState和onRestoreInstanceState
當Activity不是正常方式退出,且Activity在隨后的時間內被系統殺死之前會調用這兩個方法讓開發人員可以有機會存儲Activity相關信息,且在下次返回Activity時恢復這些數據。通過這兩個函數。開發人員能夠在某些特殊場景下儲存與界面相關的信息,提升用戶體驗。
七、總結
備忘錄模式是在不破壞封裝的條件下,通過備忘錄對象(Memoto)存儲另外一個對象內部狀態的快照,在將來合適的時候把這個對象還原到存儲起來的狀態。
優點:
給用戶提供了一種可以恢復狀態的機制,可以使用戶能夠比較方便地回到某個歷史狀態。
實現了信息的封裝,使用戶不需要關心狀態的保存細節。
缺點:
消耗資源,如果類的成員變量過多,勢必會占用比較大的資源,而且每一次保存都會消耗一定的內存。
上述就是小編為大家分享的Android中怎么實現備忘錄模式了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。