[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类,知道如何实施执行一个与请求相关的操作,任何类都可能作为一个接收者;

命令模式的优点:

  • 它能较容易的设计一个命令队列;
  • 在需要的情况下,可以较容易的将命令记入日志;
  • 允许接收请求的一方决定是否要否决请求;
  • 可以容易的实现对请求的撤销和崇左;
  • 加进新的具体命令类不影响其他的类;
  • 把[请求一个操作的对象]和[知道怎么执行一个操作的对象]隔离;
posted @ 2018-08-13 22:21  ZH奶酪  阅读(340)  评论(0编辑  收藏  举报