學習設計模式時,你是否也遇過這種情況?
「策略模式和範本方法有什麼不同?命令又為什麼出現在這裡?」
三種模式都有替換行為的感覺,很容易一直混淆。
先說重點。
策略會整套替換演算法,
範本方法固定骨架,只替換部分步驟,
命令則把「要執行的行為」封裝成物件,稍後再執行。
掌握這一句,就等於完成一半。今天就用程式碼徹底分清這三兄弟。
三種模式,一眼看懂差異
先用表格整理整體概念。
| 分類 | 策略模式 | 範本方法 | 命令模式 |
|---|---|---|---|
| 核心 | 整套替換演算法 | 固定骨架,替換部分步驟 | 將行為封裝成物件 |
| 重複使用方式 | 組合(委派) | 繼承 | 組合(委派) |
| 替換時機 | 執行階段 | 編譯時期(繼承) | 執行階段 |
| 主要關注點 | 「如何計算」 | 「順序相同,細節不同時」 | 「何時、執行什麼」 |
三種模式容易混淆,原因就在這裡。
因為它們的目的都是分離會變動的部分。
但分離方式與目的不同。我們逐一拆解。
策略模式會整套替換演算法
策略模式將多種完成同一工作的方式各自建立為獨立物件,並在需要時替換。
以付款方式為例就很貼切。
刷卡、KakaoPay、銀行轉帳:目的(付款)相同,但方法不同。
protocol PayStrategy {
func pay(_ amount: Int) -> String
}
struct CardPay: PayStrategy {
func pay(_ amount: Int) -> String { "刷卡付款 \(amount)" }
}
struct KakaoPay: PayStrategy {
func pay(_ amount: Int) -> String { "使用 KakaoPay 付款 \(amount)" }
}
var strategy: PayStrategy = CardPay()
print(strategy.pay(10000))
// 輸出:刷卡付款 10000
重點是,執行階段將 strategy 變數改成 KakaoPay(),行為就會整套替換。
重點在於透過組合(composition)委派,而不是使用繼承。
範本方法保留骨架,只替換部分內容
範本方法的思路稍有不同。
整體流程順序固定,其中幾個步驟由子類別填入。
想像煮泡麵:煮水 → 加入食材 → 完成。順序相同,只有「加入食材」不同。
class Ramen {
func cook() { // 這就是範本方法
boilWater()
addIngredients() // 只在子類別替換這個步驟
print("完成!")
}
func boilWater() { print("煮水") }
func addIngredients() { print("基本食材") }
}
class CheeseRamen: Ramen {
override func addIngredients() { print("加入起司") }
}
CheeseRamen().cook()
// 輸出:煮水 / 加入起司 / 完成!
它與策略模式的關鍵差異,是使用繼承,且只替換部分步驟。
流程(cook)的主導權掌握在父類別手中。
命令模式封裝要執行的行為
命令的關注點與前兩者完全不同。
它關心的不是如何計算,而是將行為建立為物件,以便稍後執行、取消或排入佇列。
想像遙控器按鈕就很容易。按鈕保存「開燈」這個命令,按下時才執行。
protocol Command { func execute() }
struct LightOn: Command {
func execute() { print("開燈") }
}
let button: Command = LightOn()
button.execute() // 由我決定執行時機
// 輸出:開燈
由於將請求封裝成物件,因此很自然就能加入復原(undo)、記錄日誌、工作佇列等功能。
簡單說,策略是選擇方法的模式;命令是儲存並處理請求的模式。
何時使用,何時避免
在實務上,我會依照以下標準選擇。
- 策略模式:同一目的有多種演算法,且需在執行階段切換時(排序方式、折扣政策、付款方式)
- 範本方法:處理順序固定,只有部分步驟不同時(資料剖析流程、遊戲回合進行)
- 命令:需要延後、取消、重做或排入佇列時(復原、工作排程器)
相反地,也有應該避免的訊號。
如果只有兩三個分支,未來也不會增加,就別硬套模式。單純的 if 反而更易讀。
尤其範本方法受限於繼承;若重視彈性,優先考慮策略模式(組合)通常更安全。
面試時可以這樣回答
問:策略模式與範本方法最大的差異是什麼?
策略透過組合(委派)在執行階段替換整套演算法;範本方法則透過繼承固定骨架,只覆寫部分步驟。彈性方面策略較強,流程控制則是範本方法較強。
問:命令模式與策略的差異在哪裡?
策略專注於選擇採用哪種方法;命令則將請求本身封裝成物件,支援復原、排隊、記錄等額外操作。兩者分別關注演算法選擇與請求管理。
即使三種模式看似相近,只要依照分離什麼、為什麼分離,就能清楚區分。
策略是方法,範本方法是順序中的空缺,命令是請求本身。記住這三個詞,以後就不會再混淆。祝你今天也學習愉快!

