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()