Memento 方法 – Python设计模式
备忘录方法是一种行为设计模式,它提供了将对象恢复到其先前状态的能力。在不透露具体实现细节的情况下,它允许您保存和恢复对象的先前版本。它尽量不干扰代码的封装,并允许您捕获和外部化对象的内部状态。
不使用备忘录方法的问题
想象一下,您是一名想要在竞争性编程世界中脱颖而出的学生,但您面临一个问题,即寻找一个不错的编程代码编辑器,但目前的代码编辑器都不能满足您的需求,因此您尝试为自己制作一个。任何代码编辑器最重要的功能之一是UNDO和REDO ,本质上您也需要它们。作为一个没有经验的开发人员,您只是使用了存储所有执行操作的直接方法。当然,这种方法会起作用,但效率低下!
记忆法解决方案
让我们讨论上述问题的解决方案。通过不干扰代码的封装,整个问题可以很容易地解决。当某些对象尝试执行未分配给它们的额外任务时,就会出现问题,因此它们会侵入其他对象的私有空间。 Memento 模式表示为该状态的实际所有者创建状态快照,即创建者对象。因此,与其其他对象试图从“外部”复制编辑器的状态,编辑器类本身可以制作快照,因为它可以完全访问自己的状态。
根据该模式,我们应该将对象状态的副本存储在一个名为Memento的特殊对象中,并且除了生成它的对象之外,任何其他对象都无法访问 memento 对象的内容。
Python3
"""Memento class for saving the data"""
class Memento:
"""Constructor function"""
def __init__(self, file, content):
"""put all your file content here"""
self.file = file
self.content = content
"""It's a File Writing Utility"""
class FileWriterUtility:
"""Constructor Function"""
def __init__(self, file):
"""store the input file data"""
self.file = file
self.content = ""
"""Write the data into the file"""
def write(self, string):
self.content += string
"""save the data into the Memento"""
def save(self):
return Memento(self.file, self.content)
"""UNDO feature provided"""
def undo(self, memento):
self.file = memento.file
self.content = memento.content
"""CareTaker for FileWriter"""
class FileWriterCaretaker:
"""saves the data"""
def save(self, writer):
self.obj = writer.save()
"""undo the content"""
def undo(self, writer):
writer.undo(self.obj)
if __name__ == '__main__':
"""create the caretaker object"""
caretaker = FileWriterCaretaker()
"""create the writer object"""
writer = FileWriterUtility("GFG.txt")
"""write data into file using writer object"""
writer.write("First vision of GeeksforGeeks\n")
print(writer.content + "\n\n")
"""save the file"""
caretaker.save(writer)
"""again write using the writer """
writer.write("Second vision of GeeksforGeeks\n")
print(writer.content + "\n\n")
"""undo the file"""
caretaker.undo(writer)
print(writer.content + "\n\n")
UML 图
下面是 Memento 方法的 UML 图
好处
- 鼓励封装: Memento 方法可以帮助生成对象的状态,而不会破坏客户端代码的封装。
- 简化代码:我们可以利用管理员的优势,他可以通过维护发起者代码的历史来帮助我们简化代码。
- Generic Memento 的实现:最好使用序列化来实现更通用的 memento 模式实现,而不是每个对象都需要有自己的 Memento 类实现的 Memento 模式。
缺点
- 巨大的内存消耗:如果 Originator 的对象非常巨大,那么 Memento 对象的大小也会很大并且使用大量内存,这绝对不是有效的工作方式。
- 动态语言的问题: Ruby 、 Python和PHP等编程语言是动态类型的语言,不能保证不会触及 memento 对象。
- 删除困难:删除 memento 对象并不容易,因为看守者必须跟踪发起者的生命周期才能获得结果。
适用性
- UNDO 和 REDO:大多数软件应用程序,如 Paint、Coding IDE、文本编辑器和许多其他应用程序都提供了UNDO和REDO功能,以方便客户端。
- 提供封装:我们可以使用Memento 的方法来避免客户端代码中封装的破坏,这种破坏可能是通过直接访问对象的内部实现而产生的。
进一步阅读 – Java中的 Memento 方法