第18章:备忘录模式
备忘录模式
备忘录(memento)模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
Originator
(发起人):负责创建一个备忘录Memento
,用以记录当前时刻其内部状态,并可使用备忘录恢复内部状态。Originator
可根据需要决定Memento
存储Originator
的哪些内部状态。
Memento
(备忘录):负责存储Originator
对象的内部状态,并可防止Originator
以外的其他对象访间备忘录Memento
。备忘录有两个接口,Caretaker
只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。Originator
能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。
Caretaker
(管理者):负责保存好备忘录Memento
,不能对备忘录的内容进行操作或检查。
Originator
(发起人)类
Memento
(备忘录)类
Caretaker
(管理者)类
客户端代码
备忘录模式将要保存的细节封装在Memento
中,更改保存的细节不会影响客户端。
备忘录模式的使用
-
备忘录模式适用于功能比较复杂、但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,
Originator
可以根据保存的Memento
信息还原到前一状态。 -
如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。
-
有时一些对象的内部信息必须保存在对象以外的地方,但是必须要由对象自己读取,这时,使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
-
当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
备忘录模式示例
任务:游戏进度保存
from typing import Text
class RoleStateMemento(object):
"""
角色状态存储箱类
"""
def __init__(self, vit: int, atk: int, def_: int) -> None:
self.__vit = vit
self.__atk = atk
self.__def = def_
@property
def vitality(self) -> int:
return self.__vit
@vitality.setter
def vitality(self, value: int) -> None:
self.__vit = value
@property
def attack(self) -> int:
return self.__atk
@attack.setter
def attack(self, value: int) -> None:
self.__atk = value
@property
def defense(self) -> int:
return self.__def
@defense.setter
def defense(self, value: int) -> None:
self.__def = value
class GameRole(object):
"""
游戏角色类
"""
def __init__(self) -> None:
# 生命力
self.__vit = 0
# 攻击力
self.__atk = 0
# 防御力
self.__def = 0
@property
def vitality(self) -> int:
return self.__vit
@vitality.setter
def vitality(self, value: int) -> None:
self.__vit = value
@property
def attack(self) -> int:
return self.__atk
@attack.setter
def attack(self, value: int) -> None:
self.__atk = value
@property
def defense(self) -> int:
return self.__def
@defense.setter
def defense(self, value: int) -> None:
self.__def = value
def state_display(self) -> None:
"""
状态显示
"""
print("角色当前状态:")
print("体力:{}".format(self.__vit))
print("攻击力:{}".format(self.__atk))
print("防御力:{}".format(self.__def))
def get_init_state(self) -> None:
"""
获取初始状态
"""
self.__vit = 100
self.__atk = 100
self.__def = 100
def fight(self) -> None:
"""
战斗
"""
self.__vit = 0
self.__atk = 0
self.__def = 0
def save_state(self) -> RoleStateMemento:
"""
保存角色状态
"""
return RoleStateMemento(self.__vit, self.__atk, self.__def)
def recovery_state(self, memento: RoleStateMemento) -> None:
self.__vit = memento.vitality
self.__atk = memento.attack
self.__def = memento.defense
class RoleStateCaretaker(object):
"""
角色状态管理者类
"""
def __init__(self) -> None:
self.__memento = None
@property
def memento(self) -> RoleStateMemento:
return self.__memento
@memento.setter
def memento(self, value: RoleStateMemento) -> None:
self.__memento = value
# 客户端代码
if __name__ == "__main__":
# 大战Boss前
role = GameRole()
role.get_init_state()
role.state_display()
# 保存进度
state_admin = RoleStateCaretaker()
state_admin.memento = role.save_state()
# 大战Boss时,损耗严重
role.fight()
role.state_display()
# 恢复之前状态
role.recovery_state(state_admin.memento)
role.state_display()
角色当前状态:
体力:100
攻击力:100
防御力:100
角色当前状态:
体力:0
攻击力:0
防御力:0
角色当前状态:
体力:100
攻击力:100
防御力:100