设计模式: 命令模式

场景

在大多数饭店中,当服务员已经接到顾客的点单,录入到系统中后,根据不同的菜品,会有不同的后台反应。

比如,饭店有凉菜间、热菜间、主食间,那当服务员将菜品录入到系统中后,凉菜间会打印出顾客所点的凉菜条目,热菜间会打印出顾客所点的热菜条目,主食间会打印出主食条目。

可以将该系统设计成前台服务员系统和后台烹饪系统,后台系统进一步细分成主食子系统,凉菜子系统,热菜子系统。中台则设置命令系统。

命令模式的定义

将一个请求封装成一个对象,从而可以使用不同的请求将客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。

命令模式中通常涉及三类对象的抽象:Receiver,Command,Invoker(本例中的waiter)。


f1.png

 

中介模式和命令模式的区别

只有一个Invoker的命令模式也可以抽象成一个类似的“星形网络”,但与之前介绍的中介者模式不同,

单纯的命令模式更像是一个辐射状的结构,由Invoker直接对Receiver传递命令,而一般不反向传递,

中介者模式“星形网络”的中心,是个协调者,抽象结节间的信息流全部或者部分是双向的。
另外,命令模式的定义中提到了“撤销和恢复功能”,也给了各位开发人员一个命令模式使用过程中的建议:各个Receiver中可以设计一个回滚接口,支持命令的“撤销”。

代码案例

 

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
''' 
@Author: Victor
@Contact: @163.com
@Date: 2020/8/24
@function: ''
'''


class Food(object):
    pass

# 三种处理接收者
# 主食, 潮汕砂锅粥
class StapleFood(Food):

    def __init__(self):
        pass

    def cook(self, food):
        print("Cooking the {}....".format(food))


# 凉菜: 拌黄瓜,白斩鸡
class ColdDishes(Food):
    def __init__(self):
        pass

    def cook(self, food):
        print("Mixing the {}....".format(food))


# 热菜: 抄菜心,回锅肉
class HotDishes(Food):
    def __init__(self):
        pass

    def cook(self, food):
        print("Cooking the {}....".format(food))


# 命令
class Command():
    receiver = None

    def __init__(self, receiver):
        self.receiver = receiver

    def execute(self):
        pass


class foodCommand(Command):
    dish = ""

    def __init__(self, receiver, dish):
        self.receiver = receiver
        self.dish = dish
        self.execute()

    def execute(self):
        self.receiver.cook(self.dish)


class StapleFoodCommand(foodCommand):
    pass


class CoolDishesCommand(foodCommand):
    pass


class HotDishesCommand(foodCommand):
    pass


# 调用者
class Invoker():

    def __init__(self):
        self.menu_map = dict()
        self.commandList = []

    def setDish(self, command):
        print("WAITER:Add dish")
        self.commandList.append(command)

    def cancelDish(self, command):
        print("WAITER:Cancel dish...")
        self.commandList.remove(command)

    def notify(self):
        # 通知
        print("WAITER:Nofify...")
        for command in self.commandList:
            command.execute()


# 菜单
class Menu(object):
    menu_map = dict()

    def loadMenu(self):  # 加载菜单,这里直接写死
        self.menu_map["hot"] = ["Pot-Meat", "Sauteed Tofu, Home Style", "Sauteed Snow Peas"]
        self.menu_map["cool"] = ["Cucumber", "Cut-chicken"]
        self.menu_map["staple"] = ["Rice"]

    def isHot(self, dish):
        if dish in self.menu_map["hot"]:
            return True
        return False

    def isCool(self, dish):
        if dish in self.menu_map["cool"]:
            return True
        return False

    def isStaple(self, dish):
        if dish in self.menu_map["staple"]:
            return True
        return False


if __name__ == "__main__":

    # 菜单
    menu = Menu()
    menu.loadMenu()
    # 服务员
    waiter = Invoker()
    # 顾客点菜
    dishes = ["Pot-Meat", "Cucumber", "Rice"]

    # 传入菜和接收者
    for dish in dishes:
        if menu.isCool(dish):
            cmd = CoolDishesCommand(ColdDishes(), dish)
        elif menu.isHot(dish):
            cmd = HotDishesCommand(HotDishes(), dish)
        elif menu.isStaple(dish):
            cmd = StapleFoodCommand(StapleFood(), dish)
        else:
            continue

        # 根据不同的命令上菜
        waiter.setDish(cmd)
    waiter.notify()

  

 

posted @ 2020-08-24 19:02  Adamanter  阅读(124)  评论(0)    收藏  举报