Python中的通用命令模式和命令调度模式
我在找Python中的命令模式实现...
(根据维基百科,
命令模式是一种设计模式,它用一个对象来表示和封装调用某个方法所需的所有信息,以便在以后某个时候使用。
)
我找到的唯一内容是命令分发模式:
class Dispatcher:
def do_get(self): ...
def do_put(self): ...
def error(self): ...
def dispatch(self, command):
mname = 'do_' + command
if hasattr(self, mname):
method = getattr(self, mname)
method()
else:
self.error()
也许我理解错了,但看起来这两者是不同的概念,只是名字巧合相似。
我是不是漏掉了什么?
4 个回答
4
我查了一下,发现了这个。看起来它可以很好地封装一个动作。
def demo(a,b,c):
print 'a:',a
print 'b:',b
print 'c:',c
class Command:
def __init__(self, cmd, *args):
self._cmd=cmd
self._args=args
def __call__(self, *args):
return apply(self._cmd, self._args+args)
cmd=Command(dir,__builtins__)
print cmd()
cmd=Command(demo,1,2)
cmd(3)
5
是的,你确实漏掉了一些东西:命令模式在那些没有函数指针(或者说没有把函数当作第一类对象的语言)中才是必要的,比如Java。在那些可以把函数当作对象的语言中,你可以直接使用函数本身;不需要单独创建一个命令对象(这个对象还得有个“doit”方法)。
在你提到的例子中,getattr()
调用给你返回了“命令对象”(也就是绑定的方法);在它后面加上括号就是“调用”这个命令对象。
65
最简单的命令模式已经在Python中内置了,你只需要使用一个可调用的对象:
def greet(who):
print "Hello %s" % who
greet_command = lambda: greet("World")
# pass the callable around, and invoke it later
greet_command()
命令模式作为一种面向对象的设计模式,当你的命令不仅仅是被调用时,它的意义就更大了。一个常见的使用场景是当你需要能够撤销或重做你的操作时。这时候,使用一个命令类可以很好地将前进和后退的操作结合在一起。比如:
class MoveFileCommand(object):
def __init__(self, src, dest):
self.src = src
self.dest = dest
os.rename(self.src, self.dest)
def undo(self):
os.rename(self.dest, self.src)
undo_stack = []
undo_stack.append(MoveFileCommand('foo.txt', 'bar.txt'))
undo_stack.append(MoveFileCommand('bar.txt', 'baz.txt'))
# foo.txt is now renamed to baz.txt
undo_stack.pop().undo() # Now it's bar.txt
undo_stack.pop().undo() # and back to foo.txt