跳轉到

3.1 設計思維:抽象、模組化與資訊隱藏#

系統設計是什麼#

需求回答「系統要做什麼」,系統設計(System Design)回答「系統該怎麼做」。如果說需求工程是你的「指南針」,那系統設計就是你的「藍圖」。

然而,系統設計的精髓不在於畫一張漂亮的圖,而在於三個互相關聯的核心思維:抽象(Abstraction)、模組化(Modularity)與資訊隱藏(Information Hiding)。掌握了這三個思維,你就能把 1.2 節談到的本質性困難——複雜性——管理起來。

抽象:忽略細節,聚焦本質#

抽象是軟體設計最基本的武器。它的定義很簡單:在刻意的層次上忽略不必要的細節,只保留與當前決策相關的資訊。

想一想你每天都用的「汽車」:你不用理解引擎運作、變速箱原理,只需要知道「方向盤、油門、煞車、檔位」這些介面就能開車。這就是抽象——把複雜的內部隱藏起來,只暴露必要的控制介面。

軟體中處處是抽象:

  • 函式:封裝一段邏輯,只暴露「輸入→輸出」的介面
  • 類別/介面:封裝狀態與行為,隱藏內部實作
  • 程式庫:提供一組高層功能,隱藏底層細節
  • 作業系統:抽象硬體,提供統一的檔案、行程、網路介面

抽象的力量在於:它讓你在某個層次思考時,不必同時操心所有層次。就像你寫應用邏輯時不用操心 CPU 怎麼執行指令。

但抽象也有代價——過度抽象(太多層、太多間接)會讓系統難懂、難除錯。好的抽象是「恰到好處」:剛好隱藏你不需要的細節,又不過度隱藏你需要理解的東西。

模組化:分解成可管理的單元#

抽象是「看起來像什麼」,模組化(Modularity)是「怎麼拆」。模組化把一個複雜系統拆成若干獨立的、可理解的、可替換的模組。

拆解的原則是什麼?最著名的兩句話:

  • 高內聚(High Cohesion):一個模組內部的元素,應該彼此高度相關、服務於同一個目的。(「把相關的事情放一起」)
  • 低耦合(Low Coupling):模組之間的依賴應該盡量少、盡量鬆散。(「讓不相關的事情少牽扯」)

以訂位系統為例:

┌──────────────────────────────────────────────┐
│                訂位系統                        │
├──────────────────────────────────────────────┤
│  ▲ 介面層(Web / App API)                     │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐         │
│  │ 訂位模組 │ │ 會員模組 │ │ 桌位模組 │   ← 低耦合(彼此透過介面互動)
│  └────┬────┘ └────┬────┘ └────┬────┘         │
│       ▼           ▼           ▼               │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐         │
│  │ 付款服務 │ │ 通知服務 │ │ 資料儲存 │   ← 高內聚(內部服務單一目的)
│  └─────────┘ └─────────┘ └─────────┘         │
└──────────────────────────────────────────────┘

理想的模組化,讓你可以獨立理解、獨立修改、獨立測試每個模組——這正是控制複雜性的關鍵。如果模組間耦合太緊(改 A 就得改 B 和 C),系統就會退化成一個「碰哪都會壞」的巨型怪物。

資訊隱藏:藏在介面後面的秘密#

資訊隱藏(Information Hiding) 是模組化落地的關鍵技術。它的原則:一個模組的內部設計決策,對外部是不可見的;外部只能透過定義好的介面與它互動。

這為什麼重要?想想看:如果一個模組把內部資料結構直接暴露給外部,那外部程式碼就會依賴這個內部結構。一旦內部結構需要修改(例如把陣列改成雜湊表),所有外部程式碼都跟著壞。資訊隱藏正是為了隔離變更——讓一個模組的內部可以自由演進,而不影響其他模組。

知名設計大師 David Parnas 在 1972 年提出這個概念時,舉了一個經典例子:一個模組「要為凱氏溫標計算函式提供支援」。他可以選擇把內部儲存單位鎖定為「華氏」還是「攝氏」——而這個選擇應該被隱藏起來。這樣一來,將來變更儲存單位時,只有該模組受影響,其他模組絲毫不動。

資訊隱藏的實作手段: - 私有成員變數 / Private 屬性:外部無法直接存取 - 介面 / Interface:只透過公開方法互動 - 模組邊界 / Module Boundary:跨模組只能以定義好的介面呼叫

三個思維的關係#

抽象、模組化、資訊隱藏並非三個孤立的概念,而是一個整體:

  • 抽象決定每個模組「看起來像什麼」(公開的介面)
  • 資訊隱藏決定「哪些細節是私有的、不可見的」(隱藏的實作)
  • 模組化決定「系統如何拆成這些模組」(拆分的邊界)

用一句話串起來:透過模組化把大系統拆成小單元,用抽象定義每個單元的對外介面,用資訊隱藏保護每個單元的內部秘密——三個思維合力對抗複雜性。

AI 時代的設計思維#

AI 會改變設計思維嗎?不會改變原理,但會改變實踐方式:

  • AI 生成程式碼,更需要清晰的模組邊界:因為 2.6 節談過,規格要模組化,AI 才不會因上下文過大而出錯。高內聚低耦合在 AI 時代,直接決定了 AI 產出品質。
  • 抽象降低後,AI 的審查責任反而增加:抽象層越多,AI 越容易「迷失在間接裡」。因此 AI 時代反而強調適度的抽象與清晰的模組邊界。
  • 契約 (Spec) 是模組邊界的具體化:2.6 節的介面契約,正是資訊隱藏的現代化身——用 Schema / Interface 把模組的對外介面「鎖死」,內部則交給 AI 自由實現。

本章小結#

  • 系統設計回答「系統該怎麼做」,核心是控制複雜性
  • 抽象:忽略細節、聚焦本質
  • 模組化:高內聚、低耦合地把系統拆成可管理單元
  • 資訊隱藏:把內部決策藏在介面之後,隔離變更
  • 三個思維合力對抗 1.2 節所述的本質性困難
  • AI 時代:清晰的模組邊界與介面契約,直接決定 AI 產出品質

想一想#

  1. 在你的訂位系統裡,你認為哪些應該是一個「模組」?為什麼這樣拆分符合高內聚低耦合?
  2. 「抽象」有沒有壞處?什麼時候過度抽象反而有害?
  3. 為什麼資訊隱藏能「隔離變更」?舉一個模組內部修改、外部不受影響的例子。