zoukankan      html  css  js  c++  java
  • 设计模式之备忘模式

    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()
  • 相关阅读:
    数据特征分析:5.相关性分析
    数据特征分析:4.正态分布与正态性检验
    go-文件操作
    图-迪杰斯特拉算法
    图-克鲁斯卡尔算法
    图-普利姆算法
    go-客户信息关系系统
    go-家庭收支记账软件例子
    采用邻接表表示图的深度优先搜索遍历
    广度优先搜索遍历连通图
  • 原文地址:https://www.cnblogs.com/loveprogramme/p/13097045.html
Copyright © 2011-2022 走看看