Posts 设计模式-备忘模式
Post
Cancel

设计模式-备忘模式

概念解析

备忘模式,指的是在不破坏内部结构的前提下捕获一个对象的内部状态,这样便可将该对象恢复到原先的保持状态。备忘模式的最大功能是备份,其主要的三个角色:

  • 发起人(Originator):需要进行备份的对象
  • 备忘录(Mementor):备份的状态,即一个备份的存档
  • 备忘管理者(Caretaker):备份存档的管理者,由它负责与发起人的交互

备忘模式类图如下:

img

备忘模式的优点:

  • 能够恢复之前的状态
  • 实现了信息的封装,用户不需要关心状态的保存细节

常用场景:

  • 存档/快照场景
  • 撤销/恢复功能
  • 回滚操作

设计模板

备忘模式的代码框架如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from copy import deepcopy


class Memento():
    """备忘录"""
    def set_attributes(self, dict):
        """深度拷贝字典dict中的所有属性"""
        self.__dict__ = deepcopy(dict)

    def get_attributes(self):
        """获取属性字典"""
        return self.__dict__


class Caretaker():
    """备忘录管理类"""
    def __init__(self):
        self._mementors = {}

    def add_memento(self, name, memento):
        # 不同name不同备忘录
        self._mementors[name] = memento

    def get_memento(self, name):
        return self._mementors[name]

class Originator():
    """备份发起人"""
    def create_memento(self):
        memento = Memento()
        memento.set_attributes(self.__dict__)
        return memento

    def restore_from_memento(self, memento):
        self.__dict__.update(memento.get_attributes())

实例分析

场景说明:模拟DOS命令/Linux终端命令下查看历史命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 模板中的关键类
from pattern.Memento import Originator, Caretaker, Memento
import logging


class TerminalCmd(Originator):
    """终端命令"""
    def __init__(self, text):
        self.__cmd_name = ""
        self.__cmd_args = []
        self.parse_cmd(text)

    def parse_cmd(self, text):
        """从字符串中解析命令"""
        pass

    def get_arguments_from_string(self, str, split_flag):
        """通过split_flag进行分割,获取参数数组"""
        pass

    def show_cmd(self):
        print(self.__cmd_name, self.__cmd_args)


class TerminalCaretaker(Caretaker):
    """终端命令的备忘录管理类"""
    def show_history_cmds(self):
        """显示历史命令"""
        for key, obj in self._mementors.items():
            name = ""
            value = []
            if obj._TerminalCmd.__cmd_name:
                name = obj._TerminalCmd.__cmd_name
            if obj._TerminalCmd.__cmd_args:
                value = obj._TerminalCmd.__cmd_args
            print("第%s条命令:%s %s" % (key, name, value))


def test_terminal():
    cmd_idx = 0
    caretaker = TerminalCaretaker()
    cur_cmd = TerminalCmd("")
    while True:
        str_cmd = input("请输入指令:")
        str_cmd = str_cmd.lower()
        if str_cmd.startswith("q"):
            exit(0)
        elif str_cmd.startswith("h"):
            caretaker.show_history_cmds()
        # 通过"!"符号表示获取历史的某个指令
        elif str_cmd.startswith("!"):
            idx = int(str_cmd[1:])
            cur_cmd.restore_from_memento(caretaker.get_memento(idx))
            cur_cmd.show_cmd()
        else:
            cur_cmd = TerminalCmd(str_cmd)
            cur_cmd.show_cmd()
            caretaker.add_memento(cmd_idx, cur_cmd.create_memento())
        cmdIdx += 1
This post is licensed under CC BY 4.0 by the author.

设计模式-代理模式

设计模式-适配模式