Clean Architecture 實作篇 (五)

網頁層轉接器實作

elliot
Feb 8, 2024

首先回到熟悉的六角架構圖,對於最外層 Web 可以認知是一個透過瀏覽器互動的 使用者介面,而接著進入的是與外部溝通的 Adapter 轉接器 (Controller),透過 轉接埠 (Port) 來與 應用程式層(Service) 的 使用案例 互動

而之所以 轉接器使用案例 之間,需要增加一層介面的原因是 明確的建立起 外部應用程式核心 互動時的規格。 意思是說對於使用案例來說,不論轉接器是由 Web端 或是 Message Bus端 都能呼叫,抑或是當我們的使用案例有時候需要回傳外部 或是儲存需求時,因為不能直接呼叫外部的低層級細節,所以這時候就需要一個介面提供 反向依賴。

這樣可以降低耦合度,可以更容易地替換不同的轉接器,提高可測試性,簡化維護。

一個網頁層轉接器的職責

將 HTTP 轉成對應的 Request Object -> 驗證授權 (OAuth, Middleware) -> 輸入檢查 -> 轉換成對應的使用案例輸入模型 -> 呼叫使用案例 -> 將使用案例輸出對應為 Response Object -> 透過 HTTP 回傳

對於MVC架構來說,我們通常把這些職責交給了 Controller,那我們是否該依據每個使用案例不同,而將 Controller 也拆成單一控制器呢?

讓我們先了解如果都不拆,都聚焦在同一隻 Controller 上會帶來哪些影響

  1. 維護性差 (因為很難找到正確的使用案例)
  2. 可測試度差 (因為需要建構子注入每一個 輸入轉接埠,很難針對單個使用案例進行測試)
  3. 變相地促使重複利用資料結構 (因為新增和修改可能都需要 同個輸入模型,只不過新增的不需要id,導致輸入模型不在乾淨 可能有欄位因此變成了 nullable,那我該如何驗證資料模型正不正確? 當我為了某個使用案例去調整輸入模型時,是不是也會影響到其他使用案例)

而好處就是部署成本較低,當異動時,可以只單純抽換該檔案。

而對於拆分的方式,可以把 各項作業從 套件結構 和 控制器類別 上切開,並盡量使用 與 使用案例相關的名稱來命名那些方法和類別。

意思就是說 依據使用案例去規劃套件結構

user/
├── register/
│ └── RegisterUserController.php
└── update/
└── UpdateUserController.php

雖然這樣做會建立很多不共用模組,產生許多小型規模類別,但這樣做能使 更好的尋找使用案例、測試、平行開發

--

--