设计模式之备忘模式

from copy import deepcopy
import logging, time


# 备忘模式中主要有三个角色:发起人(需要进行备份的对象)、备忘录(备份的状态,即一个备份的文档)、备忘录管理者(备份文档的管理者,由他负责人与发起人的交互)
# 应用场景:1、需要保存/恢复对象的状态或数据时,如游戏的存档、虚拟机的快照
#          2、需要撤销、恢复功能的场景
#          3、提供一个可回滚的操作,如数据库的事务管理
class Memento:
    """备忘录"""

    def __init__(self):
        self.cmdName = ""
        self.cmdArgs = []

    def setAttributes(self, _dict):
        """深度拷贝字典dict中的所有属性"""
        self.__dict__ = deepcopy(_dict)

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

    def __repr__(self):
        return self.cmdName + " " + " ".join(self.cmdArgs)

class Caretaker:
    """备忘录管理类"""

    def __init__(self):
        self._mementos = {}

    def addMemento(self, memento):
        name = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        self._mementos[name] = memento

    def getMemento(self, name):
        return self._mementos[name]


class Originator:
    """备份发起人"""

    def createMemento(self):
        memento = Memento()
        memento.setAttributes(self.__dict__)
        return memento

    def restoreFromMemento(self, memento):
        self.__dict__.update(memento.getAttributes())


# Doc历史指令存储
class TerminalCmd(Originator):
    """终端命令"""

    def __init__(self, text):
        self.cmdName = ""
        self.cmdArgs = []
        self.parseCmd(text)

    def parseCmd(self, text):
        """从字符串中解析命令"""
        subStrs = self.getArgumentsFromString(text, " ")
        # 获取第一个字段作为命令的名称
        if len(subStrs) > 0:
            self.cmdName = subStrs[0]

        if len(subStrs) > 0:
            self.cmdArgs = subStrs[1:]

    def getArgumentsFromString(self, _str, splitFlag):
        """通过splitFlag进行分割,获得参数数组"""
        if splitFlag == "":
            logging.warning("splitFlag为空!")
            return ""
        data = _str.split(splitFlag)
        result = []
        for item in data:
            item.strip()
            if item != "":
                result.append(item)
        return result

    def showCmd(self):
        print(self.cmdName, self.cmdArgs)


class TerminalCaretaker(Caretaker):
    """终端命令的备忘录管理器"""

    def showHistory(self):
        """显示历史命令"""
        for key, memento in self._mementos.items():
            print(key + ":", memento)


def testTerminal():
    caretaker = TerminalCaretaker()
    curCmd = TerminalCmd("")
    while True:
        strCmd = input("请输入指令:")
        strCmd = strCmd.lower()
        if strCmd.startswith("q"):
            exit(0)
        elif strCmd.startswith("h"):
            caretaker.showHistory()
        elif strCmd.startswith("!"):
            idx = strCmd[1]
            curCmd.restoreFromMemento(caretaker.getMemento(idx))
            curCmd.showCmd()
        else:
            curCmd = TerminalCmd(strCmd)
            curCmd.showCmd()
        caretaker.addMemento(curCmd.createMemento())


testTerminal()
原文地址:https://www.cnblogs.com/loveprogramme/p/13097045.html