# Chapter6: 命令模式 (Command Pattern)

## This section contain the following items:

* 1.Command Pattern
* 2.Command Pattern Example: Test Scheduler

## 1.Command  Pattern

* 命令模式要解決的問題:

  * 1.當我們要實踐的物件們, 其模式為**控制器(或是下命令者), 命令以及被下令者**, 而且後續有擴充其他種類的可能時, 逐一實踐每組模擬器會有**控制器種類太多造成使用者不方便的問題**, **我們希望可以提供一種控制器(或API)全吃**
  * 2.使用單一模擬器, 並在裡面放許多if判斷顯然不是好的設計方式(違反**開放封閉**原則)(以下圖片引用自"深入淺出設計模式")

  ![](https://1330730840-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M4M0G8D7wlLIQ3stULq%2F-M4M0IKc4rWLYnAL_jem%2F-M4M0LopsKR3-JPspX7d%2F%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202017-05-06%20%E4%B8%8B%E5%8D%882.24.23.png?generation=1586302919370773\&alt=media)
* 因此要如何解決以上問題呢? 就是利用命令模式
  * Client + 動作的要求者 + 動作的執行者 + 接收者(被下令者) = 命令模式
    * 將不同種類的**動作執行者**封裝成物件, 其**動作要求者**不需要知道命令的種類, 只要使用者知道就好
    * 這種做法除了可將**動作要求者**與**動作執行者**解耦以便於擴充外, 也方便後續將**動作**裝載到佇列等.
* 角色(以下圖片引用自"深入淺出設計模式")

  * Client: 主程式
  * 動作的要求者 (Invoker): 下令執行動作, 但不需知道執行後發生什麼事
    * setCommand()
  * 動作的執行者 (Command): 動作所封裝成的物件
    * execute()
  * 接收者 (Receiver): 被控制的對象
    * action()

  ![](https://1330730840-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M4M0G8D7wlLIQ3stULq%2F-M4M0IKc4rWLYnAL_jem%2F-M4M0LorM-JHvEnyn6AS%2F%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202017-05-06%20%E4%B8%8B%E5%8D%882.32.26.png?generation=1586302919152295\&alt=media)
* 命令模式的優點及應用
  * 1.巨集命令
  * 2.佇列命令
    * 將不同種類的命令儲存起來, 在適當的時機啟動

## 2.Command Pattern Example: Command Scheduler

* 1.需求
  * 主程式從config檔中讀取script的路徑並儲存於佇列中, 並循序呼喚起
* 2.軟體架構設計

![](https://1330730840-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M4M0G8D7wlLIQ3stULq%2F-M4M0IKc4rWLYnAL_jem%2F-M4M0Lot76_5pxk4feQb%2F%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202017-05-06%20%E4%B8%8B%E5%8D%882.49.08.png?generation=1586302919078556\&alt=media)
