本章主軸#

整本書以「設計模式」為主軸,但目的更深:透過模式建立一套新的物件導向心智模型。本章把這條線索整理成一份清單,回答最根本的問題——「為什麼要那樣寫?」

物件導向原則摘要(新觀點)#

  • 物件是有明確職責的東西
  • 物件對自己負責
  • 封裝是「任何形式的隱藏」:資料、實作、類別、設計、實例化
  • 用 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 個結構,而是在練「對真實之物的敏銳度