[Python设计模式] 第23章 烤串的哲学——命令模式
github地址:https://github.com/cheesezh/python_design_patterns
题目1
用程序模拟,顾客直接向烤串师傅提需求。
class Barbecuer():
def bake_mutton(self):
print("烤羊肉串")
def bake_chicken_wing(self):
print("烤鸡翅")
def main():
boy = Barbecuer()
boy.bake_mutton()
boy.bake_mutton()
boy.bake_mutton()
boy.bake_chicken_wing()
boy.bake_mutton()
boy.bake_mutton()
boy.bake_chicken_wing()
main()
烤羊肉串
烤羊肉串
烤羊肉串
烤鸡翅
烤羊肉串
烤羊肉串
烤鸡翅
点评
客户端程序与“烤串师傅”紧耦合,尽管简单,但是极为僵化,当顾客多了,请求多了,就容易乱了。
题目2
用程序模拟,顾客向服务员提需求,服务员再告知烤串师傅。
from abc import ABCMeta, abstractmethod
class Command():
"""
抽象命令类
"""
__metaclass__ = ABCMeta
# 需要确定一个命令接收者
def __init__(self, receiver):
self.receiver = receiver
@abstractmethod
def excute_command(self):
pass
class BakeMuttonCommand(Command):
"""
具体命令类
"""
def excute_command(self):
self.receiver.bake_mutton()
def to_string(self):
return "烤羊肉串"
class BakeChickenWingCommand(Command):
"""
具体命令类
"""
def excute_command(self):
self.receiver.bake_chicken_wing()
def to_string(self):
return "烤鸡翅"
class Waiter():
"""
服务员类, 不用管顾客的烤串要怎么烤,对于服务员来说,都当作命令记录下来就行,然后通知“烤串师傅”执行即可。
"""
def __init__(self):
self.orders = []
def set_order(self, cmd):
if cmd.to_string() == "烤鸡翅":
print("鸡翅没了,换点其他的吧")
else:
self.orders.append(cmd)
print("增加订单:", cmd.to_string())
def cancel_order(self, cmd):
self.orders.remove(cmd)
print("取消订单:", cmd.to_string())
def notify(self):
for cmd in self.orders:
cmd.excute_command()
def main():
# 开店准备
boy = Barbecuer()
bake_mutton_1 = BakeMuttonCommand(boy)
bake_mutton_2 = BakeMuttonCommand(boy)
bake_chicken_wing = BakeChickenWingCommand(boy)
girl = Waiter()
# 开门营业
girl.set_order(bake_mutton_1)
girl.set_order(bake_mutton_2)
girl.set_order(bake_chicken_wing)
# 开始制作
girl.notify()
main()
增加订单: 烤羊肉串
增加订单: 烤羊肉串
鸡翅没了,换点其他的吧
烤羊肉串
烤羊肉串
命令模式
命令模式,讲一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销操作。[DP]
主要包括以下几种类:
- Command类,用来声明执行操作的接口,每个Command类都需要绑定一个命令接收者(执行者);
- ConcreteCommand类,将一个命令接收者对象绑定与一个动作,调用接收者相应的操作,以实现Execute;
- Invoder类,比如服务员,维护命令队列,发起执行命令的请求;
- Receiver类,知道如何实施执行一个与请求相关的操作,任何类都可能作为一个接收者;
命令模式的优点:
- 它能较容易的设计一个命令队列;
- 在需要的情况下,可以较容易的将命令记入日志;
- 允许接收请求的一方决定是否要否决请求;
- 可以容易的实现对请求的撤销和崇左;
- 加进新的具体命令类不影响其他的类;
- 把[请求一个操作的对象]和[知道怎么执行一个操作的对象]隔离;
找我内推: 字节跳动各种岗位
作者:
ZH奶酪(张贺)
邮箱:
cheesezh@qq.com
出处:
http://www.cnblogs.com/CheeseZH/
*
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。