Python設計模式之命令模式

命令模式——封裝調用

  • 命令模式是一種行爲設計模式,他用於封裝觸發事件(完成任何一個操作)所包含的所有信息。一般有方法名稱,擁有方法對象,方法參數等。

一個安裝嚮導的例子:每一步選擇的都會存在Command對象裏,在最後一步點擊finish的時候,Command會運行execute進行安裝。

class Wizard(object):
    def __init__(self, src, rootdir):

        self.choices = []
        self.rootdir = rootdir
        self.src = src

    def preferences(self, command):
        self.choices.append(command)

    def execute(self):

        for choice in self.choices:
            if list(choice.values())[0]:
                print("Copying binaries --", self.src, " to ", self.rootdir)
            else:
                print("No Operation")


if __name__ == '__main__':
    wizard = Wizard('python', 'bin')
    wizard.preferences({'python': True})
    wizard.preferences({'java': False})
    wizard.execute()

實現

證券交易所的例子

我想賣一個股票,在開市之前我提交給證券交易所賣股票申請,等股市一開,證券交易所就幫我賣掉

# 客戶下訂單的接口
from abc import ABCMeta, abstractmethod


class Order(metaclass=ABCMeta):
    @abstractmethod
    def execute(self):
        pass


# 具體實現類
# 買賣方法,execute來執行
class BuyStockOrder(Order):
    def __init__(self, stock):
        self.stock = stock

    def execute(self):
        self.stock.buy()


class SellStockOrder(Order):
    def __init__(self, stock):
        self.stock = stock

    def execute(self):
        self.stock.sell()


# StockTrade實現buy和sell方法
class StockTrade:
    def buy(self):
        print('買股票')

    def sell(self):
        print('賣股票')


# 調用者
class Agent:
    def __init__(self):
        self.__orderQueue = []

    def place_order(self, order):
        self.__orderQueue.append(order)
        order.execute()


if __name__ == '__main__':
    # 客戶端
    stock = StockTrade()
    buy_stock = BuyStockOrder(stock)
    sell_stock = SellStockOrder(stock)

    # 命令者
    agent = Agent()
    agent.place_order(buy_stock)
    agent.place_order(sell_stock)
    
    '''結果
    買股票
    賣股票'''

命令模式的優缺點

優點

  • 把調用操作的類與知道如何執行該操作的對象分開了
  • 結合隊列可以創造一系列命令
  • 添加命令方便,不用改現有代碼
  • 可以用命令模式定義回滾系統

缺點

  • 要很多類和對象協作,要確保正確
  • 每個單獨的命令都是一個類,增加了實現和維護的類的數量
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章