GOF设计模式分三大类:
备忘录模式(Memento Pattern)
定义:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
解决问题:如何在软件中实现撤销功能?
使用场景:
组成:
补充说明:
优点:
缺点:
使用备忘录模式来设计中国象棋软件,提供“悔棋”功能
### 备忘录模式
"""原发器:象棋棋子"""
class Chessman:
def __init__(self, label: str, x: int, y: int):
self.label = label
self.x = x
self.y = y
def save(self) -> "ChessmanMemento":
# 保存状态
return ChessmanMemento(self.label, self.x, self.y)
def restore(self, memento: "ChessmanMemento"):
# 恢复状态
self.label = memento.label
self.x = memento.x
self.y = memento.y
"""备忘录:象棋棋子备忘录"""
class ChessmanMemento:
def __init__(self, label: str, x: int, y: int):
self.label = label
self.x = x
self.y = y
"""负责人:象棋棋子备忘录管理"""
class MementoCaretaker:
def __init__(self):
self.memento: ChessmanMemento = None
def get_memento(self):
return self.memento
def set_memento(self, memento: ChessmanMemento):
self.memento = memento
def display(chess: Chessman):
print(f"棋子 {chess.label} 当前位置为:行 {chess.x} 列 {chess.y}")
if __name__ == "__main__":
mc = MementoCaretaker()
chess = Chessman("车", 2, 2)
display(chess)
mc.set_memento(chess.save()) # 保存状态
chess.y = 4
display(chess)
mc.set_memento(chess.save()) # 保存状态
chess.x = 5
display(chess)
print("###悔棋###")
chess.restore(mc.get_memento()) # 恢复状态
display(chess)
棋子 车 当前位置为:行 2 列 2
棋子 车 当前位置为:行 2 列 4
棋子 车 当前位置为:行 5 列 4
###悔棋###
棋子 车 当前位置为:行 2 列 4
实现多次撤销
"""负责人:象棋棋子备忘录管理"""
class MementoCaretaker:
def __init__(self):
self.memento_list_f: list[ChessmanMemento] = [] # 前进状态
self.memento_list_b: list[ChessmanMemento] = [] # 悔棋状态
def get_memento_f(self):
# 用于悔棋
self.memento_list_b.append(self.memento_list_f.pop())
return self.memento_list_f[-1]
def get_memento_b(self):
# 用于撤销悔棋
memento = self.memento_list_b.pop()
self.memento_list_f.append(memento)
return memento
def set_memento(self, memento: ChessmanMemento):
# 下棋保存状态
self.memento_list_b.clear() # 棋子前进,则清空悔棋状态
self.memento_list_f.append(memento)
def display(chess: Chessman):
print(f"棋子 {chess.label} 当前位置为:行 {chess.x} 列 {chess.y}")
def play(chess: Chessman, mc: MementoCaretaker):
# 下棋
mc.set_memento(chess.save()) # 保存备忘录
display(chess)
def undo(chess: Chessman, mc: MementoCaretaker):
# 悔棋
print("###悔棋###")
chess.restore(mc.get_memento_f())
display(chess)
def redo(chess: Chessman, mc: MementoCaretaker):
# 撤销悔棋
print("###撤销悔棋###")
chess.restore(mc.get_memento_b())
display(chess)
if __name__ == "__main__":
mc = MementoCaretaker()
chess = Chessman("车", 1, 1)
play(chess, mc)
chess.y = 4
play(chess, mc)
chess.x = 5
play(chess, mc)
undo(chess, mc)
undo(chess, mc)
redo(chess, mc)
redo(chess, mc)
棋子 车 当前位置为:行 1 列 1
棋子 车 当前位置为:行 1 列 4
棋子 车 当前位置为:行 5 列 4
###悔棋###
棋子 车 当前位置为:行 1 列 4
###悔棋###
棋子 车 当前位置为:行 1 列 1
###撤销悔棋###
棋子 车 当前位置为:行 1 列 4
###撤销悔棋###
棋子 车 当前位置为:行 5 列 4
您正在阅读的是《设计模式Python版》专栏!关注不迷路~