一 定义
在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态
二 ULM类图
-
Originator:负责创建一个备忘录,可以记录、恢复自身的内部状态。同时Originator还可以
根据需要决定Memento存储自身的哪些内部状态。 -
Memento:备忘录角色,用于存储 Originator的内部状态,并且可以防止Originator以外的对象访问Memento。
-
Caretaker:负责存储备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象。
三. 优缺点
优点:
- 提供可以恢复状态的机制
- 实现了信息的封装,不用关心保存状态的细节
缺点:
消耗资源(如果类的成员变量过多,每次保存都会消耗一定的内存)
四. 代码示例
4.1 首先创建一个游戏类,这里以使命召唤为例
.首先创建一个游戏类,这里以使命召唤为例 (Originator)
class CallOfDuty {
var TAG = "CallOfDuty"
var mCurrentLevel = 1
var mLifeBar = 100
var mGun:String? = "汉阳造"
fun play(){
Log.d(TAG,"使命召唤")
mLifeBar = mLifeBar?.minus(10)
mCurrentLevel ++
mGun = "沙漠之鹰+Ak47"
Log.d(TAG,"晋升到第"+mCurrentLevel+"关,当前血量:" + mLifeBar
+",当前武器:" + mGun)
}
fun quit(){
Log.d(TAG,"--------quit--------")
Log.d(TAG,"退出前的游戏属性:\n" + this.toString())
Log.d(TAG,"--------已退出--------")
}
fun createMemote() :Memote{
var memote = Memote()
memote.mCurrentLevel = this.mCurrentLevel
memote.mLifeBar = this.mLifeBar
memote.mGun = this.mGun
return memote
}
fun restore(memote:Memote){
this.mCurrentLevel = memote.mCurrentLevel!!
this.mLifeBar = memote.mLifeBar!!
this.mGun = memote.mGun
}
override fun toString(): String {
return "CallOfDuty{" + "mCurrentLevel=" + mCurrentLevel + ", mLifeBar="+
mLifeBar + ", mGun=" +mGun
}
}
4.2 创建一个备份存储类
class Memote {
var mCurrentLevel:Int? = null
var mLifeBar : Int? = null
var mGun:String? = null
override fun toString(): String {
return "Memote{" + "mCurrentLevel=" + mCurrentLevel + ", mLifeBar="+
mLifeBar + ", mGun=" +mGun
}
}
4.3 创建一个备份管理者类,用于读档存档类
class Caretaker {
var mMemote : Memote? = null
fun saveMemote(memote: Memote){
this.mMemote = memote
}
fun getMemote() : Memote? {
return mMemote
}
}
4.4 最后创建实例进行调用
以游戏存档为例, 屏蔽了外界对CallOfDuty对象的直接访问, 进行退出存档和进入时读档操作
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var game = CallOfDuty()
game.play()
//存档
var caretaker = Caretaker()
caretaker.saveMemote(game.createMemote())
//退出
game.quit()
//恢复游戏
var newgame = CallOfDuty()
Log.d(TAG,"恢复存档前属性:\n" + newgame.toString())
newgame.restore(caretaker.getMemote()!!)
Log.d(TAG,"恢复存档后属性:\n" + newgame.toString())
}
五 Android源码中的应用
Activity的onSaveInstanceState(),onRestoreInstanceState()两个方法,非主动退出或跳转到其他activity时触发onSaveInstanceState备份数据,下次启动activity时读取备份