案例研究:影片販售 (Case Study: Video Sales)#

為了證明整潔架構原則不僅僅是理論,Uncle Bob 在這一章帶領我們進行了一個紙上的案例研究:設計一個「影片販售網站」。 這個過程展示了如何從最初的分析(識別角色),一步步走到元件的劃分。

一、第一步:識別角色與使用案例#

架構設計的第一步,不是設計資料庫,也不是選 Web 框架,而是搞清楚系統是為誰服務的

1. 確定角色 (Actors)#

根據 SRP(單一職責原則),我們必須將系統依照「改變的原因」進行分割。在這個案例中,改變的原因來自於不同的角色:

  • 作者 (Author): 上傳影片、撰寫描述。
  • 管理者 (Admin): 審核影片、刪除違規內容。
  • 購買者 (Purchaser): 購買影片執照。
  • 觀眾 (Viewer): 觀看影片。

目標: 我們希望系統的切割方式,能確保當「作者」要求修改功能時,不會影響到「管理者」或「觀眾」的程式碼。

2. 確定使用案例 (Use Cases)#

針對每個角色,我們列出他們的操作。 值得注意的是,作者在此提取了兩個抽象使用案例

  • Purchase License(購買執照)
  • View Catalog(檢視目錄) 這並非絕對必要,但提早識別出這些共通性,有助於未來的重用與繼承。

二、初步的元件架構#

確定了使用案例後,我們就可以開始畫出元件架構圖。 這裡遵循了典型的整潔架構流程: View $\rightarrow$ Controller $\rightarrow$ Interactor $\rightarrow$ Presenter $\rightarrow$ View

1. 部署選項的開放性#

作者設計出的初步架構,並沒有硬性規定這些元件要如何打包(Deploy)。這正是好架構的特徵——保留選項。 視當下情況,我們可以有不同的部署方式:

  • 單體 (Monolith): 所有 View, Interactor, Controller 打包成一個 .jar
  • 依層級分 (By Layer): 所有 View 一包,所有 Interactor 一包。
  • 依元件分 (By Component): 「影片目錄」相關的一包,「影片播放」相關的一包。

三、架構的雙重維度#

這張架構圖最精華的部分,在於它同時展示了兩種維度的分離:

1. 水平分離:依據 SRP (角色)#

  • 切分依據: 改變的原因(Reason to change)。
  • 作法: 將支援「作者」的程式碼與支援「購買者」的程式碼分開。
  • 結果: 系統被切分為 Admin, Author, Purchaser, Viewer 等區塊。

2. 垂直分離:依據依賴規則 (層級)#

  • 切分依據: 改變的速率(Rate of change)與依賴方向。
  • 作法: 將 UI(Web)、控制器、業務邏輯(Interactors)分層。
  • 結果: 依賴箭頭嚴格地從低層級(View/Controller)指向高層級(Interactor)。

總結: 這個案例展示了架構師如何運用兩把刀來解剖系統:

  1. SRP 之刀進行水平切割(隔離不同角色的變更)。
  2. 依賴規則 之刀進行垂直切割(隔離業務邏輯與介面細節)。 最終產出的架構,既能獨立部署,也能獨立開發,且完全獨立於框架與資料庫。