一個好架構須同時支援系統四大需求:使用案例、運行、開發、部署。
為達這目標,架構師的核心武器是 「解耦(Decoupling)」。
一、架構支援的四大支柱#
1. 使用案例 (Use Cases)#
- 顯眼性: 架構須讓使用案例成為「一等公民」。系統的意圖(Intent)應在架構中清晰可見
- 結構: 透過將特定行為化為顯眼類別或模組,名稱應清楚描述功能(如
AddOrder,DeleteUser)
2. 運行 (Operation)#
- 靈活性: 硬體升級可以解決效能問題,但架構應保留將元件分離到不同伺服器運行的選項(如將高運算量的服務獨立出來)
- 通訊: 元件間若保持適當距離且不預設通訊方式,
未來面對運行需求的變化(如從單機變成分散式)會更容易
3. 開發 (Development)#
- 康威定律 (Conway’s Law): 架構會反映組織結構
- 隔離: 為讓多團隊能並行開發且互不干擾,系統應被分隔成完全隔離、可獨立開發的元件
4. 部署 (Deployment)#
- 即時性: 目標是「熱交換(Hot-swap)」
- 解耦: 如果元件與使用案例都良好解耦,新增功能只需加入新的
jar/dll,
而不需重新編譯或部署整個系統
二、解耦的策略:切蛋糕的藝術#
要實現上述獨立性,我們須在兩維度上解耦:
1. 水平分層 (Horizontal Layers)#
這最常見,依照技術角色切分:
- UI 層
- 應用程式特定業務規則
- 企業級業務規則
- 資料庫層
- 目的: UI 的變更不應影響業務邏輯;資料庫的更換不應影響 UI
2. 垂直切分 (Vertical Slices)#
依照使用案例切分。
- 概念: 每個使用案例(如「新增訂單」)都是一個垂直切片,它貫穿了 UI、業務邏輯到資料庫
- 目的: 透過將「新增訂單」與「刪除訂單」分開,新增一個使用案例時,不會干擾到舊有案例
三、重複的迷思 (The Myth of Duplication)#
工程師常被教導要「消除重複(Don’t Repeat Yourself, DRY)」。但在架構層次,有些重複是好的。
| 重複類型 | 定義 | 處理方式 |
|---|---|---|
| 真重複 | 兩段程式碼一模一樣,且總為相同理由而改變 | 須消除 |
| 假重複(意外重複) | 兩段程式碼目前看來一樣,但未來會沿著相異路徑發展 | 須保留 |
常見陷阱:
許多人喜歡將「資料庫的 Entity」直接拿來當作「UI 的 View Model」使用,因為欄位看來一樣。
這是錯誤的。 UI 和資料庫會因完全不同的理由改變。
如果綁在一起,未來 UI 改動就會意外影響資料庫層。
請容忍這種「假重複」,分開定義這兩個類別。
四、解耦的模式 (Decoupling Modes)#
我們可以在不同層次上實現解耦,這取決於專案的規模與需求:
| 層級 | 描述 | 優點 | 缺點 |
|---|---|---|---|
| 原始碼層級 (Source Level) | 單體 (Monolithic)。 元件在同記憶體位址, 透過函式呼叫通訊 | 簡單、速度快 | 依賴關係複雜, 難以獨立部署 |
| 部署層級 (Deployment Level) | DLL/JAR/Gem。 透過動態連結通訊, 但可獨立發佈 | 可獨立部署, 版本控管容易 | 仍需在同程序 (Process)中運行 |
| 服務層級 (Service Level) | 微服務 (Microservices)。 透過網路封包通訊 | 完全隔離, 最高獨立性 | 網路延遲、分散式系統 的複雜性高 |
架構師的智慧:
好架構不會在專案早期就鎖死在「微服務」模式(過度設計)。
好架構允許你從單體開始,隨著系統成長,能平滑地將某些部分轉移到部署甚至服務層級。
解耦模式會隨時間改變。