命令模式(Command Pattern),舉生活中的例子才好懂,懂吃一蘭拉麵就懂命令模式 - 設計模式

Posted by: Max Chen | in Design Pattern | 1 year ago |

一,為什麼需要設計模式?

在軟體工程中,“行為請求者”與“行為實現者”通常呈現“高耦合”。

但有時候,如要對行為進行“記錄、撤銷/重做、事務”等處理,這種無法抵禦變化的高耦合是不合適的。

如何將“行為請求者”與“行為實現者”解耦,將一組行為抽象為對象,實現二者之間的松耦合?

"利用Invoker與Command",這就是命令模式(Command Pattern)。

二,命令模式的架構

  • Invoker
  • Command (Interface)
  • ConcreteCommand
  • Receiver
  • Client

這些都是啥?真得很亂阿!沒關係不重要,直接看看生活中的例子!

image

三,命令模式生活例子的例子,點一碗一蘭拉麵

from abc import ABC, abstractmethod
import queue

class 顧客:
    def __init__(self,nickname):
        print(nickname)

    def eat(self,meal):
        return meal

class 一蘭拉麵:
    def __init__(self):
        #一蘭拉麵店員跟師傅合作點餐跟出餐
        self.invoker = 店員()
        #一蘭拉麵師傅做拉麵
        self.receiver = 師傅()
        #一蘭拉麵有賣師傅做的豚骨拉麵
        self.concreteCommand_豚骨拉麵 = 一份豚骨拉麵(self.receiver)
        #一蘭拉麵有賣師傅做的醬油拉麵
        self.concreteCommand_醬油拉麵 = 一份醬油拉麵(self.receiver)
        print("一蘭拉麵公告,疫情關係,由店員按自助點餐機")

    def order(self,meal):
        if meal=="豚骨拉麵":
            self.invoker.確認餐點命令(self.concreteCommand_豚骨拉麵)
            self.invoker.出餐()
        else:
            self.invoker.確認餐點命令(self.concreteCommand_醬油拉麵)
            self.invoker.出餐()
        print("點了一份 %s" % meal)


class 店員:
    commandorders = queue.Queue()

    def __init__(self,):
        self.name = "店小二"
        # print(self.name)

    # 將餐點命令放入commandorders隊列
    def 確認餐點命令(self,點餐機):
        self.commandorders.put(點餐機)
    # 將餐點命令移出commandorders隊列
    def 取消餐點命令(self,點餐機):
        self.commandorders.get(點餐機)
    # 請師傅開始製作,並將餐點命令移出commandorders隊列
    def 出餐(self):
        while self.commandorders.empty():
            concreteCommand = self.commandorders.get(點餐機)
            concreteCommand.exeute()

class 師傅:
    def __init__(self):
        self.name = "陳師傅"
        # print(self.name)
    def 製作豚骨拉麵(self):
        print("%s 開始製作豚骨拉麵" %self.name)

    def 製作醬油拉麵(self):
        print("%s 開始製作醬油拉麵" %self.name)

class 點餐機(ABC):  # 命令:抽象類
    @abstractmethod 
    def execute(self): 
        """做什麼拉麵"""

class 一份豚骨拉麵(點餐機):  # 命令:實作類

    def __init__(self,receiver):
        self.name = "一份豚骨拉麵"
        self.receiver=師傅()
        # print(self.name)
    def execute(self):
        self.receiver.製作豚骨拉麵()

class 一份醬油拉麵(點餐機):  # 命令:實作類

    def __init__(self,receiver):
        self.name = "一份醬油拉麵"
        self.receiver=師傅()
        # print(self.name)
    def execute(self):
        self.receiver.製作醬油拉麵()

if __name__=="__main__":
    client = 一蘭拉麵()
    顧客("吃貨小明").eat(client.order("豚骨拉麵"))

情境說明:

小明去"一蘭拉麵",想要點一碗豚骨拉麵,但是疫情關係,現在皆由"店員"操作點餐機,店員開始操作點餐機:

"點餐機"上面有好多命令,其中有一項是"一碗豚骨拉麵",店員確認小明要點一碗豚骨拉麵,請"師傅"做了一碗豚骨拉麵後,小明自取。

情境分析:

  1. 點餐機:這就是上述架構圖的"Command",點餐機上面可以有很多餐點命令(所以是抽象類,因為有很多餐點命令)。

  2. 一份豚骨拉麵:這就是上述架構圖的"ConcreteCommand",在點餐機上,除了有一份豚骨拉麵,也有一份醬油拉麵,一份地獄拉麵...,然而這只是命令,真正實作的是"師傅(Receiver)"

  3. 師傅:這就是上述架構圖的"Receiver"(行為實作者),師傅就負責實作,至於要做什麼?ConcreteCommand派師傅做什麼就做什麼

  4. 店員:這就是上述架構圖的"Invoker"!店員確認要點一份豚骨拉麵,還是一份醬油拉麵,店員可以決定出餐順序/要不要出餐:

    也就是究竟命令要不要做,什麼時候做,全都可以由Invoker控制!

  5. 一蘭拉麵:這就是上述架構圖的"Client"",擁有上述所有實體類(點餐機是抽象類)的類(行為請求者)

這樣是不是更好理解呢,總之,以上這種模式就是命令模式:

Client要進行生產(拉麵),是叫 Invoker ConcreteCommand(Command) Receiver 去煮要生產的各種拉麵。

註:[附上找到的優缺點與使用時機,供參考,依照情況彈性使用](https://baike.baidu.com/item/%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F/7277118)

image

Reference:

https://blog.xuite.net/rubyintainan/blog/324083320 https://zh.wikipedia.org/zh-tw/%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F https://www.runoob.com/design-pattern/command-pattern.html https://notfalse.net/4/command-pattern#i-11

Currently unrated
 or 

Subscribe

* indicates required

Recent Posts

Archive

2023
2022
2021

Categories

Apache 1

Data Science 2

Dbfit 1

Design Pattern 1

Devops 4

DigitalOcean 1

Django 1

English 3

Excel 5

FUN 4

Flask 3

Git 1

HackMD 1

Heroku 1

Html/Css 1

Linux 4

MDX 1

Machine Learning 2

Manufacture 1

Master Data Service 1

Mezzanine 18

Oracle 1

Postgresql 7

PowerBI 4

Powershell 4

Python 22

SEO 2

SQL Server 53

SQL Server Analytics Service 1

SQLite 1

Windows 1

database 8

work-experience 1

其他 1

投資入門 1

投資心得 2

時間管理 1

總體經濟 2

自我成長 3

資料工程 1

Tags

SEO(1) Github(2) Title Tag(2) ML(1) 李宏毅(1) SQL Server(18) Tempdb(1) SSMS(1) Windows(1) 自我成長(2) Excel(1) python Flask(1) python(5) Flask(2)

Authors

Max Chen (159)

Feeds

RSS / Atom

命令模式(Command Pattern),舉生活中的例子才好懂,懂吃一蘭拉麵就懂命令模式 - 設計模式

© COPYRIGHT 2011-2022. Max的文藝復興. ALL RIGHT RESERVED.