设计模式(python实现)--命令模式(Command)
2020-01-28 本文已影响0人
远行_2a22
Command
动机(Motivation)
- ”行为请求者“与”行为实现者“通常呈现一种”紧耦合“。但在某些场合——比如需要对行为进行”记录、撤销、事务“等处理,这种无法抵御变化的紧耦合是不合适的。
- 在这种情况下,如何将”行为请求者“与”行为实现者“解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。
- 命令设计模式帮助我们将一个操作(撤销、重做、复制、粘贴等)封装成一个对象。简而言之,这意味着创建一个类,包含实现该操作所需要的所有逻辑和方法
- 调用命令的对象与知道如何执行命令的对象解耦。调用者无需知道命令的任何实现细节。
- 如果有意义,可以把多个命令组织起来,这样调用者能够按顺序执行它们。例如,在实现一个多层撤销命令时,这是很有用的。
模式定义
将一个请求(行为)封装成一个对象,从而使你可用不用的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
——《设计模式》GoF
要点总结
- Command模式的根本目的在于将”行为请求者“与”行为实现者“解耦,在面向对象语言中,常见的实现手段是”将行为抽象为对象“。
- 与C++中的函数对象类似,C++函数对象以函数签名来定义行为接口规范,更灵活性能更高。
例子
# -*- coding:utf-8 -*-
import os
class RenameFile:
def __init__(self, path_src, path_dst):
self.src, self.dst = path_src, path_dst
def execute(self):
print("[renaming '{}' to '{}']".format(self.src, self.dst))
os.rename(self.src, self.dst)
def undo(self):
print("[rename undo: renaming '{}' back to '{}']".format(self.dst, self.src))
os.rename(self.dst, self.src)
class CreateFile:
def __init__(self, path, txt='hello world\n'):
self.path, self.txt = path, txt
def execute(self):
print("[creating file '{}']".format(self.path))
with open(self.path, mode='w') as out_file:
out_file.write(self.txt)
def undo(self):
os.remove(self.path)
print("[creat undo: delete file '{}']".format(self.path))
if __name__ == '__main__':
cmd_list = []
create_cmd = CreateFile(r'create_test.text')
cmd_list.append(create_cmd)
rename_cmd = RenameFile(r'create_test.text', r'rename_test.text')
cmd_list.append(rename_cmd)
for cmd in cmd_list:
cmd.execute()
start_undo = False
if start_undo:
print('*'*30)
print('start undo')
# 注意命令需要倒序撤销
for cmd in reversed(cmd_list):
cmd.undo()
通过将操作封装成cmd对象,存入list,可以进行撤销等操作。