本章主軸#
本章把上一章的「以模式思考(thinking in patterns)」實際套用在 CAD/CAM 問題上,與第 4 章的初版解法做對照。最後得出的設計大幅減少類別數,並能輕鬆應對未來 V3。
思考流程#
| 步驟 | 內容 |
|---|---|
| 1. 識別模式 | 找出問題中存在的模式 |
| 2. 分析並套用 | 對每個模式重複以下小步: |
| 2a. 排序脈絡 | 找出哪個模式為哪個建立脈絡 |
| 2b. 套用模式擴展設計 | 拿排在最前的模式做高層設計 |
| 2c. 識別新模式 | 過程中可能浮現新模式 |
| 2d. 重複 | 對剩下未整合的模式重複 |
| 3. 補上細節 | 完善方法與類別 |
「以模式思考」並非萬用——只能在問題能用既知模式描述時奏效。一般情況下會結合下一部介紹的 共通/差異分析(CVA)。
步驟 1:識別模式#
在前面章節中,作者已從 CAD/CAM 問題抽出四個候選模式:
- Abstract Factory
- Adapter
- Bridge
- Facade
步驟 2a:找出 seniormost pattern#
「Seniormost」是作者用語,指為其他模式建立脈絡的最外層模式。判斷方式:
- 兩兩配對比較
- 看是否一個模式的存在與意義由另一個決定
通則:使用先於建立#
一條重要規則:先決定要哪些物件,再決定如何建立它們。
處理「如何使用」的模式,會為處理「如何建立」的模式設定脈絡。
依此原則,Abstract Factory 一定排在最後(除非另一個建立類模式並列)。
比較剩下三個模式#
- Bridge vs Adapter:Bridge 定義了實作要符合的介面,Adapter 才知道要把 V2 的 OOGFeature 轉成什麼樣。Bridge 為 Adapter 建立脈絡。
- Bridge vs Facade:Facade 把 V1 的繁瑣呼叫封起來,Bridge 的實作端會使用這個 Facade。Bridge 為 Facade 建立脈絡。
Bridge 勝出,是 seniormost pattern。
步驟 2b:套用 Bridge#
從整體看,系統把 CAD/CAM 模型轉成 NC set。中央類別是 Model,內含一群 Feature。

Figure 13-5: Model 設計——Model 含一群 Feature 子類(Slot、Hole、Cutout 等)

Figure 13-6: 使用繼承處理兩種 Model 類型——V1Model 與 V2Model

Figure 13-7: 用 Bridge 處理 Model 的兩種版本——但因只有實作變動,這裡不真的需要 Bridge
Feature為 Bridge 中的 Abstraction- 衍生出
SlotFeature、HoleFeature、CutoutFeature、SpecialFeature、IrregularFeature - 對
Implementation端,定義ImpFeature,讓V1Imp、V2Imp各自實作

Figure 13-8: Bridge 模式的通用結構——Abstraction、RefinedAbstraction、Implementor、ConcreteImplementor

Figure 13-9: 套用 Bridge 後的設計——Feature 抽象 + ImpFeature 實作
ImpFeature 的介面包含:
getX、getY、getLength- 部分特徵專用方法如
getEdgeType
Model本身沒有真正的 Bridge——只有實作隨版本不同。直接以繼承做出V1Model、V2Model即可,不需強行套 Bridge。
步驟 2c:尋找新出現的模式#
掃過目前設計後沒有新模式浮現。剩下的工作是把 V1、V2 串接進來——交給 Facade 與 Adapter。
一個額外收穫:套用 Bridge 後可看出 V1、V2 在 feature 物件眼中其實已可互換——這個彈性在原本充滿細節的設計中被隱藏起來了。
步驟 2a/2b 重複:套用 Facade(V1 端)#
V1 是一堆 C 風格函式呼叫。建立 V1Facade:
- 對外提供
V1Imp真正需要的簡化方法 - 內部呼叫 V1 模組
V1Imp持有自己的 model number 與 feature ID,依此向V1Facade詢問
每個 Feature 會對應一個 V1Imp,因為 V1 需要每個 feature 自己記住識別資訊。
步驟 2a/2b 重複:套用 Adapter(V2 端)#
V2 提供物件導向的 OOGFeature。建立 V2Imp 包住 OOGFeature,讓它能以 ImpFeature 介面被使用。
步驟 2a/2b 重複:Abstract Factory?#
最終結論:不需要。
- 起初判斷 Abstract Factory 適用於「同版本下要拿一整組 V? feature」
- 但
Model物件本身已經知道現在用的是哪個版本,能直接負責建立 - 既然已有清楚的封裝,不需要硬塞模式
一開始把 Abstract Factory 列入考慮並不是浪費——它幫助我們從多角度檢視問題。錯估某模式存在不會帶來損失,反而能釐清思路。
步驟 3:補上細節#
Feature子類只擁有概念性方法(getLocation、getLength),不含實作資訊V1Imp知道自己對應的 V1 model 與 feature ID,再向V1Facade取資料V2Imp持有對應的OOGFeature,把請求轉發過去
與第 4 章解法的對照#

Figure 13-12: 第 4 章的初版解法——5 種 Feature × 2 個 CAD/CAM 版本造成類別爆炸
用「念」的方式比較#
第一版:Model 包含 Features;Feature 是 slot/hole/cutout/…;Slot 又分 V1Slot 與 V2Slot;V1Slot 用 V1 系統、V2Slot 用 OOGSlot;Hole 又分 V1Hole 與 V2Hole;V1Hole 用 V1 系統、V2Hole 用 OOGHole⋯⋯
第二版:Model 包含 Features;Feature 是 slot/hole/cutout/…;所有 Feature 都包含一個實作物件,它是 V1 實作或 V2 實作;V1 實作透過 V1Facade 存取 V1,V2 實作把 OOGFeature 包成 Adapter。
第二版「念」起來短得多,也更乾淨。
V3 出現時#
- 第一版:每種 feature 都要新增一個 V3 衍生類
- 第二版:只需新增一個 Adapter(或 Facade),舊類別完全不動
本章要記住的事#
- 「先用後造」:先決定要哪些物件,再思考怎麼建立它們
- 透過比對哪個模式為哪個建立脈絡,可找到 seniormost pattern
- 模式並非套愈多愈好;不適用就乾脆放掉
- 從整體脈絡推導出的設計,能直接展現可擴展性
- 用「念」整個設計圖,是一個簡單但有效的好設計檢驗法