本章是 Part III 的總結章節,將前五章(Ch 8–12)所探討的各種面向彙整為一幅完整的圖景,說明邁向深層洞察的重構是一個怎樣的多面向過程,以及團隊應以什麼心態來面對它。
三件必須聚焦的事#
作者開宗明義指出,Refactoring Toward Deeper Insight 需要同時聚焦於三件事:
- 活在領域之中(Live in the domain) — 持續沉浸在業務領域裡
- 不斷以不同角度看待事物(Keep looking at things a different way) — 對既有模型保持質疑與探索
- 與 Domain Expert 維持不間斷的對話(Maintain an unbroken dialog with domain experts) — 確保開發者與領域專家之間的溝通從未中斷
追求對領域的洞察(seeking insight into the domain)為重構過程創造了更寬廣的脈絡,使之超越傳統意義上「看到壞程式碼就改」的微觀重構。
Initiation — 重構的起點#
重構的觸發方式多種多樣:
- 程式碼出現問題 — 某處的複雜度或彆扭感(complexity or awkwardness),讓開發者意識到根本原因出在 Domain Model 上,可能是缺少某個概念,或某段關係有誤
- 程式碼看起來整潔,但模型語言與領域專家脫節 — 這是與傳統重構觀點的重要差異:觸發點不一定是程式碼品質,而是模型的表達力不足
- 新需求無法自然融入現有模型
- 開發者的學習帶來新理解 — 隨著對領域更深的理解,看見了更清晰或更有用的模型機會
作者強調,發現問題所在(seeing the trouble spot)往往是最困難、最不確定的部分。一旦辨識出問題,開發者就能系統性地尋找新模型的元素——與同事和領域專家腦力激盪,或借助 Analysis Patterns、Design Patterns 等系統化知識。
Exploration Teams — 探索團隊#
當模型的改進不是幾小時內就能完成的小幅調整時,就需要組成一個短期的探索小組:
運作方式#
- 發起者找 2–3 位擅長思考此類問題、熟悉該領域或建模能力強的開發者
- 若涉及微妙之處,確保有 Domain Expert 參與
- 一組 4–5 人到會議室或咖啡廳,進行 半小時到一個半小時的腦力激盪
- 畫 UML 圖、用物件走過情境(walking through scenarios)、確認領域專家理解並認為模型有用
- 滿意就回去寫程式;若需要沉澱,隔幾天再聚一次
保持高效產出的關鍵#
- Self-determination(自主決定) — 小團隊可以臨時組成、運作幾天後解散,不需要長期的組織架構
- Scope and sleep(控制範圍並讓想法沉澱) — 兩三次短會議、分散在幾天之內,就應該產出一個值得嘗試的設計。如果卡住了,代表一次處理太多,應該縮小範圍
- Exercising the Ubiquitous Language(鍛鍊通用語言) — 讓團隊成員(尤其是領域專家)參與腦力激盪,是精煉 Ubiquitous Language 的絕佳機會;最終成果是一套經過精煉的語言,由開發者帶回並在程式碼中正式化
flowchart TD
Start[識別建模問題] --> Team["組成探索團隊\n2-3 位開發者 + Domain Expert"]
Team --> Session["腦力激盪\n30 分鐘 ~ 1.5 小時"]
Session --> Methods["畫 UML、走過情境\n嘗試不同表達"]
Methods --> Validate{達成共識?}
Validate -->|是| Implement[回去寫程式碼]
Validate -->|否| Retry["隔幾天再聚\n帶入新觀點"]
Retry --> SessionPrior Art — 善用既有知識#
不必總是從零開始。腦力激盪過程有強大的能力去吸收來自各種來源的想法,與在地知識結合,持續 Knowledge Crunching:
- 領域本身的書籍與知識 — 該領域的專業人士可能已經整理過概念、找到有用的抽象,這些可以讓結果更豐富、更快產出,也更容易被領域專家接受
- Analysis Patterns — 專門針對軟體開發、基於實際實作經驗的模式,能提供精妙的模型概念並幫助避免許多錯誤,但它們不是食譜,而是 Knowledge Crunching 的養分
- Design Patterns — 當它同時符合實作需求與模型概念時,可以運用在 Domain Layer 中
- 形式化系統(Formal Systems) — 當算術或謂詞邏輯等形式化方法適合某個領域片段時,可以將該部分抽離並套用形式化規則,產生緊湊且容易理解的模型
A Design for Developers — 為開發者而設計#
軟體不只是為使用者而存在,也是為開發者而存在。
在迭代式開發中,開發者需要反覆修改程式碼、將程式碼與系統其他部分整合。Refactoring Toward Deeper Insight 既催生 Supple Design,也受益於 Supple Design:
- 傳達意圖(communicates intent) — 容易預期程式碼執行的效果,也容易預期修改的後果
- 降低心智負擔(limit mental overload) — 主要透過減少依賴與副作用
- 基於深層模型 — 只在對使用者最關鍵的地方細緻化,讓變更最頻繁之處保持彈性,其餘地方保持簡潔
Timing — 重構的時機#
不要等到能完整論證才行動#
作者明確警告:如果你等到能為一個變更做出完整的正當化論述,那就已經等太久了。 專案已在承受沉重成本,而被延後的變更只會更難執行,因為目標程式碼已被進一步擴展並嵌入其他程式碼之中。
大多數團隊對重構仍然過於保守。他們看得見修改程式碼的風險和開發者時間的成本,卻看不見維持一個笨拙設計的風險和繞過該設計的成本。要求開發者為重構決策提供正當理由看似合理,卻會讓本就困難的事變得不可能,最終壓制了重構(或將其逼入地下)。
何時應該重構#
- 設計未能表達團隊當前對領域的理解
- 重要概念隱含在設計中(且你看到了讓它們顯式化的方法)
- 你看到了讓設計某個重要部分變得更 supple 的機會
何時不該重構#
- 不要在 release 前一天重構
- 不要引入只是炫技的 Supple Design,卻未切中領域核心
- 不要引入你無法說服領域專家使用的「深層模型」,無論它看起來多優雅
不要絕對化,但要把舒適圈的邊界往偏好重構的方向推進。
Crisis as Opportunity — 危機即轉機#
作者以生物學的 Punctuated Equilibrium(間斷平衡) 理論作為類比:長期的漸進變化或穩定狀態,會被相對短暫的劇烈變化所打斷,然後進入新的平衡。軟體開發的節奏也是如此。
突破的特徵#
- 傳統重構聽起來非常平穩,但 Refactoring Toward Deeper Insight 通常不是
- 一段穩定的模型精煉期,可能突然帶來撼動一切的洞察
- 這樣的 Breakthrough 不是天天發生,但通往 Deep Model 和 Supple Design 的大部分重要變更都源自於此
危機的本質是進步#
這種情境往往看起來不像機會,更像是危機:模型突然出現明顯的不足、表達上的巨大空洞,或者某些陳述根本就是錯的。但這意味著團隊已經到達了新的理解層次——從更高的視角回望,舊模型顯得拙劣,而他們已能構想出一個遠為優秀的模型。
持續的過程#
Refactoring Toward Deeper Insight 是一個永不止歇的過程:
- 隱含概念被辨識出來並顯式化(Implicit concepts are recognized and made explicit)
- 設計的某些部分變得更 supple,可能採用 Declarative Style
- 開發突然來到突破的邊緣並一躍而入,抵達 Deep Model
- 然後穩定的精煉再次開始
這個循環不斷重複,每一輪都將團隊帶向更深層的理解與更優秀的設計。
flowchart TD
Steady["穩定精煉期\n持續小幅改善"] --> Discover["隱含概念被辨識\n並顯式化"]
Discover --> Supple["設計變得\n更加 Supple"]
Supple --> Edge["逼近突破邊緣\n(危機即機會)"]
Edge --> Breakthrough["突破!\n模型跳躍式進化"]
Breakthrough --> NewSteady["新的均衡狀態\n更深層的理解"]
NewSteady --> Steady