為何需要重新定義「複雜」#
Chapter 1 確立了耦合的角色:耦合是把系統黏起來的必要力量。那麼讓系統變得失序、難以管理的力量是什麼?答案是複雜度(complexity)。
要管理複雜度,先要能定義它、辨認它。本章引入 Dave Snowden 提出的 Cynefin 框架,給「複雜」一個夠精準、可操作的定義。
Cynefin 是威爾斯文,發音類似「kuh-nev-in」(Dan North 的口訣是「念 Kevin,但中間打個噴嚏」)。
複雜度的直覺定義#
我們常憑直覺使用「複雜」這個詞,但精確下定義並不容易。本書採取的工作定義是:
複雜度反映人在面對某個系統時的認知負擔(cognitive load)。認知負擔越大,就越難理解、控制、預測這個系統。
軟體設計中,複雜度的代價特別具體:
- 元件像拼圖,無法單看一塊就理解功能,必須拼起來才能看懂
- 想修改系統時,難以判斷該動哪裡、改了之後會牽動什麼
- 越複雜,修改所需的努力越多
複雜度是主觀的:對你而言複雜,對另一個專家可能簡單。例如汽車毛病對車主可能棘手數週,對資深技師可能十分鐘搞定。
正因為主觀,討論軟體設計時需要更精確的模型——這就是 Cynefin 的價值。
Cynefin 的五個領域#
Cynefin 把決策情境分成五個領域。前四個是核心,第五個(disorder)是「不知道自己在哪一個」的退路。
Clear(清晰)#
- 行動的後果明確且可預測
- 有規則或最佳實踐可循
- 決策流程:Sense → Categorize → Respond
- 例子:紅綠燈——識別號誌、對應規則、依規則停或走
Complicated(繁雜)#
- 屬於「已知的未知(known unknowns)」:你知道自己缺什麼知識,可以找專家補
- 決策流程:Sense → Analyze → Respond
- 例子:車子壞掉,你不知道原因,但可以找技師診斷、依其建議修
Complex(複雜)#
- 屬於「未知的未知(unknown unknowns)」:你不知道自己缺什麼,或這份知識根本不存在,因此找不到專家
- 結果跟脈絡綁在一起,沒有任何通用建議能準確預測
- 決策流程:Probe → Sense → Respond——必須先做安全實驗,觀察結果,再決定下一步
- 例子:A/B 測試。沒人能事先精準預測哪個按鈕顏色 CTR 較高,只能先放出去看數據

Figure 2.1: A/B 測試是複雜領域中決策的常見範例
在複雜領域中,失敗是學習過程的必要組成部分。預期單一實驗能解答一切,本身就是錯誤的期待。
Chaotic(混沌)#
- 因果關係根本斷裂,連回顧都看不出
- 沒有專家可問、沒有實驗可做(不可能或結果隨機)
- 決策流程:Act → Sense → Respond——憑直覺先做動作把局面拉回複雜領域,再分析
- 例子:擲骰子、玩輪盤;或火災等緊急狀況,根本沒時間實驗
Disorder(失序)#
- 你不知道自己究竟在哪個領域
- 唯一的行動是「先辨認出當前屬於哪一個領域」
較新版本的 Cynefin 把 disorder 細分為 aporia(你意識到自己缺資訊)與 confusion(你誤判了領域而不自知)。本書為求簡潔不做區分。
四個領域的差異對照#
四個領域的核心差別在於因果關係的耦合程度:
| 領域 | 因果關係 | 所需知識 | 行動方式 |
|---|---|---|---|
| Clear | 緊耦合 | 已知 | 分類(Categorization) |
| Complicated | 緊耦合但不顯而易見 | 已知的未知 | 分析(Analysis) |
| Complex | 鬆耦合 | 未知的未知 | 實驗(Experimentation) |
| Chaotic | 解耦 | 「不可知」 | 信任直覺 |
把這個觀念帶回耦合主題:複雜度本身就是「行動」與「結果」之間的鬆耦合。
軟體設計中的 Cynefin#
Cynefin 不只是哲學工具,也能直接指導軟體設計決策。書中以兩個情境示範。
範例 A:整合外部服務 NotificationMaster#
需要送 SMS,考慮整合既有的 NotificationMaster.SendSMS。同樣需求,依細節差異可能落在四個領域:
- Clear:方法接受
PhoneNumber型別,建構子明確要求 E.164 國際格式

Figure 2.2: 整合外部元件——清晰(Clear)
- Complicated:方法只接受
string,文件未說明格式——但你可以去問模組作者

Figure 2.3: 整合外部元件——繁雜(Complicated)
- Complex:模組屬於 legacy 系統,沒人懂、看不到原始碼,只能不斷試誤找出可用格式
- Chaotic:API 後方有 load balancer 指向不同版本的服務,相同輸入時而成功時而失敗

Figure 2.4: 整合外部元件——混沌(Chaotic)
注意一個有趣的轉換:在 Complex 領域中試出可用格式之後,下一個整合者可以「諮詢你」,於是同樣的問題就降為 Complicated。領域是會隨知識累積而轉移的。
範例 B:修改資料庫索引#
修改 RDB 索引可能造成什麼影響?
- Clear:資料庫專屬於你的微服務,所有查詢都在你掌控之內

Figure 2.5: 修改資料庫索引——清晰(Clear)
- Complicated:另有一個團隊使用部分資料,但你知道是哪個團隊,可以協調

Figure 2.6: 修改資料庫索引——繁雜(Complicated)
- Complex:你知道有別人在用,但不知道是誰、用法為何——只能靠 staging 上的整合與效能測試「探測」
- Chaotic:你完全不知道有人在用,沒有自動化測試保護,部署後另一個元件開始 timeout——只能憑直覺先 rollback
Cynefin 與「複雜度」的精確意義#
Cynefin 幫我們把日常語言中的「複雜」收斂成更精確的定義:
- 認知負擔高,不一定就是 complex——若有專家可問就只是 complicated
- 完全沒有因果關係不是 complex,那是 chaotic
全書接下來統一採用 Cynefin 的定義:複雜(complex)= 高度不確定,因果關係鬆耦合,需要安全實驗才能揭示因果。
英文中 complex 與 complicated 常被當成同義詞。Cynefin 刻意把兩者分開,源自拉丁文也支持這種區分:
- complicated:源自 complicare(折疊在一起)
- complex:源自 complexus(部件的聚合)
重點整理#
做設計決策前,先問自己:「我現在身處哪個 Cynefin 領域?」對應該採用 Sense-Categorize-Respond、Sense-Analyze-Respond、Probe-Sense-Respond,還是 Act-Sense-Respond?
每當你發現自己「先做個小實驗才敢決定」,停下來想一想——你正在處理的就是複雜性。
下一章會延伸這個討論:在「系統」的脈絡中,複雜度究竟是怎麼長出來的?