表示器與謙卑物件 (Presenters and Humble Objects)#

在軟體開發中,總有一些部分特別難以測試(例如 GUI 畫面、資料庫整合)。 為了讓這些部分也能被納入測試覆蓋範圍,Uncle Bob 介紹了一個強大的設計模式:謙卑物件模式(The Humble Object Pattern)

一、謙卑物件模式#

這個模式的核心思想是: 將原本難以測試的行為拆解成兩個模組(類別)。

  1. 謙卑模組 (The Humble Module):
    • 包含所有難以測試的行為(如直接操作 DOM、繪製像素)。
    • 邏輯非常簡單、甚至近乎愚蠢(Dumb),以至於不需測試(因為太簡單了,幾乎不可能寫錯)。
    • 因為它什麼都不懂,所以很「謙卑」。
  2. 邏輯模組 (The Logic Module):
    • 包含所有與該行為相關的邏輯。
    • 完全不依賴 GUI 或 DB。
    • 易於測試

二、經典案例:Presenters 與 Views#

這是謙卑物件模式最常見的應用,發生在 UI 邊界上。

1. View (謙卑物件)#

  • 角色: 它是 GUI 的外殼。
  • 職責: 只負責將數據載入螢幕。它不應該做任何決策(例如:不該決定「因為餘額是負的所以顯示紅色」,只該負責「顯示紅色」)。
  • 測試: 難以測試,但因為邏輯已被剝離,所以不需要測試。

2. Presenter (邏輯模組)#

  • 角色: 它是 View 的大腦。
  • 職責: 接受來自應用程式的資料,並將其格式化為 View 可以直接使用的形式。
    • Date 物件轉換成字串 "2023-10-27"
    • Money 物件轉換成字串 "$100.00"
    • 決定布林旗標(如 isRedText = true)。
  • 測試: 非常容易測試,因為它只是在操作單純的資料結構。

3. View Model#

Presenter 與 View 之間傳遞的是一個單純的資料結構,稱為 View Model

  • 它只包含字串、布林值和列舉(Enums)。
  • View 只是盲目地讀取 View Model 中的欄位並顯示出來。

三、其他應用:資料庫閘道器#

這個模式不僅用於 UI,也用於資料庫邊界。

  • SQL 是謙卑的: SQL 語句本身難以測試(需要連線 DB)。
  • Interactor 是邏輯的: 業務邏輯不該包含 SQL。
  • Gateway (謙卑物件): 介面轉接層中的 Gateway 負責執行 SQL。這部分被視為謙卑物件,實作簡單的 CRUD,而複雜的查詢邏輯則盡量移至可測試的 Interactor 中。

總結: 謙卑物件模式是「架構邊界」的守護者。 透過將難以測試的「介面」與易於測試的「邏輯」分離,我們能大幅提升系統的可測試性,確保業務邏輯(Presenter/Interactor)即便在沒有 UI 或 DB 的情況下也能被完整驗證。