命令模式

壹頁書發表於2017-03-20

命令模式

1、內容

命令模式是一個高內聚的模式,其定義為:Encapsulate a request as an object,there by letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(將一個請求封裝成一個物件,從而讓你使用不同的請求把客戶端引數化,對請 求排隊或者記錄請求日誌,可以提供命令的撤銷和恢復功能。)

2、角色

Receiver接受者角色:該角色就是幹活的角色,命令傳遞到這裡是應該被執行Command命令角色:需要執行的所有命令都在這裡宣告 Invoker呼叫者角色:接收到命令,並執行命令

**3、優點 **

類間解耦:呼叫者角色與接收者角色之間沒有任何依賴關係,呼叫者實現功能時只需呼叫Command 抽象類的execute方法就可以,不需要了解到底是哪個接收者執行。

可擴充套件性:Command的子類可以非常容易地擴充套件,而呼叫者Invoker和高層次的模組Client不產生嚴 重的程式碼耦合。

命令模式結合其他模式會更優秀:命令模式可以結合責任鏈模式,實現命令族解析任務;結合模板方法模式,則可以減少 Command子類的膨脹問題。

4、缺點

命令模式也是有缺點的,請看Command的子類:如果有N個命令,問題就出來 了,Command的子類就可不是幾個,而是N個,這個類膨脹得非常大,這個就需要讀者在項 目中慎重考慮使用。

5、程式碼示例

命令模式
在請求者和請求實現者之間,把請求抽象成命令,並新增一個命令接受和分發者,實現請求者和實現者的解耦
如客戶(請求者)去燒烤店吃飯,並不需要認識燒烤boy(實現者),只需要有選單(命令),服務員(命令接收和分發者),然後根據
選單給服務員下單就好了。然後選單有會有記錄,我們可以要求撤銷和重做,燒烤店可以拒絕我們的某個選單。
優點:1、可以有一個命令列表;2、命令可以很容易寫入日誌;3、命令可以被撤銷或重做;4、命令實現者可以拒絕命令;5、實現了請求者
和實現者的解耦;6、要加入新的命令很容易,增加個命令類,實現者能做對應的命令
複製程式碼
from abc import ABCMeta, abstractmethod


class Cooker(object):
   """
   廚師
   """
   def __init__(self):
       self._num_yang = 1
       self._num_niu = 1

   def cook_yang(self):
       if self._num_yang <= 3:
           print("燒烤羊肉串")
           self._num_yang += 1
       else:
           print("沒羊肉串了")

   def cook_niu(self):
       if self._num_niu <= 3:
           print("燒烤牛肉串")
           self._num_niu += 1
       else:
           print("沒牛肉串了")


class Command(object):
   """
   抽象選單
   """
   __metaclass__ = ABCMeta

   def __init__(self, name):
       self.cooker = Cooker()
       self.name = name

   @abstractmethod
   def cook(self):
       pass


class CommandYang(Command):
   def __init__(self, name):
       super(CommandYang, self).__init__(name)

   def cook(self):
       self.cooker.cook_yang()


class CommandNiu(Command):
   def __init__(self, name):
       super(CommandNiu, self).__init__(name)

   def cook(self):
       self.cooker.cook_niu()


class Waiter(object):
   def __init__(self):
       self._command_list = []
       self._menu = None
       self._kehu = None

   def set_kehu(self, kehu):
       self._kehu = kehu

   def set_order(self, command, num=1):
       print("加菜:" + command.name)
       for i in range(num):
           self._command_list.append(command)

   def remove_order(self, command, num=1):
       print("減菜:" + command.name)
       try:
           for i in range(num):
               self._command_list.remove(command)
       except Exception as e:
           print("沒點那麼多菜")

   def notify(self):
       print("下單啦:")
       self._menu = Order(self._kehu, self._command_list)
       self._menu.show()
       for command in self._command_list:
           command.cook()
       self._command_list = []
       print("")


class Order(object):
   def __init__(self, name, command_list):
       self._command_list = command_list
       self._name = name

   def set_order(self, command_list):
       self._command_list = command_list

   def set_name(self, name):
       self._name = name

   def show(self):
       print(self._name + ",您的選單是:")
       for command in self._command_list:
           print(command.name)
       print("")


if __name__ == '__main__':
   # 燒烤店初始化
   command_yang = CommandYang("羊肉串")
   command_niu = CommandNiu("牛肉串")
   waiter = Waiter()

   # 營業
   waiter.set_kehu("張三")
   waiter.set_order(command_yang, 4)
   waiter.set_order(command_niu, 5)
   waiter.notify()
複製程式碼

命令模式

識別圖中二維碼,領取python全套視訊資料

相關文章