本章主軸#
整本書以「設計模式」為主軸,但目的更深:透過模式建立一套新的物件導向心智模型。本章把這條線索整理成一份清單,回答最根本的問題——「為什麼要那樣寫?」
物件導向原則摘要(新觀點)#
- 物件是有明確職責的東西
- 物件對自己負責
- 封裝是「任何形式的隱藏」:資料、實作、類別、設計、實例化
- 用 CVA 抽象出行為與資料的變化
- 面向介面設計
- 用繼承來「概念化變化」,而不是「特化」
- 把不同變動軸維持解耦
- 強凝聚 + 鬆耦合
- 把使用與建立分開
- 嚴格遵守「Once and only once」
- 透過 program by intention 與意圖揭示性命名提升可讀性
- 寫程式前先想可測試性
模式如何「封裝實作」#
GoF 的模式幾乎都在做同一件事:把實作從 Client 隱藏起來。
- Bridge 隱藏 Abstraction 的實作細節
- Strategy 隱藏 ConcreteStrategy 的實作
- Decorator、Iterator、Proxy 等亦同
隱藏實作的價值在於:未來新增實作時,Client 不必跟著改。
CVA 與設計模式#
許多模式都可由 CVA 推導出來——Strategy、Iterator、Proxy、State、Visitor、Template Method、Decorator、Composite、Abstract Factory、Bridge……
反過來說,知道模式能幫你「看見」CVA 找出來的概念屬於哪個模式。Bridge 就告訴你「畫圖程式」與「形狀」是兩個獨立變動軸。
把問題拆成「責任」#
- CVA 找出 commonality(概念)與 variability(具體)
- 模式進一步告訴我們:可以把問題拆成「使用者 + 被使用的責任」
- Decorator 拆成「主功能 + 可選擇的裝飾」;Strategy 拆成「使用規則的物件 + 規則本身」
模式即「脈絡設計」的縮影#
許多模式正是依賴倒置原則的具體展現:
- Bridge:在 Abstraction 衍生的脈絡下定義 Implementation
- Decorator:在原 Component 的脈絡下定義 Decorator
- Abstract Factory:在整體問題脈絡下決定家族成員
抽象類別本身的介面,就是其衍生類別必須在其中實作的「脈絡」。設計到介面就是脈絡設計。
模式真正重要的是「關係」#
「在最後階段,模式已經不重要了——模式教會了你對真實之物保持敏銳。」——Christopher Alexander
模式真正重要的是它揭露的力量、動機、關係。模式只是一種談論這些關係的語言。
每個模式都包含四個面向:
- 解決一組力量
- 提供議題檢查清單
- 提供共同術語
- 連結一整個知識體(body of knowledge)
模式與敏捷實踐#
把模式誤解為「罐頭解法」會讓人以為它與敏捷相對立。
但模式背後的精神(封裝變動、面向介面、可測試)正是敏捷追求的目標。模式是 XP / TDD 的好朋友,不是對手。
學模式時可問自己的五個問題#
| 問題 | 用途 |
|---|---|
| 它隱藏什麼實作? | 找出可被替換的部分 |
| 包含什麼共通性? | 找出抽象 |
| 各物件的責任為何? | 切分職責 |
| 各物件之間的關係? | 看見力量 |
| 模式如何體現脈絡設計? | 領會背後哲學 |
本章重點#
- 物件導向的「新觀點」是把封裝、繼承、抽象重新理解為對變動的處理
- 模式 = 把實作藏起來 + 把責任分開 + 把關係描述清楚
- CVA 找出抽象,模式描述抽象之間的關係
- 重要的不是模式本身,而是它讓我們看見真實的關係與力量
- 學模式不是在背 23 個結構,而是在練「對真實之物的敏銳度」