Software Design - Modularization

前述

首先幾篇文章是基於 Clean Architecture 的基礎,建議先閱讀以下連結已具備基礎知識

The missing chapter

  • CA 原著 Chapter 34 - The missing chapter - Actual implementation details of an architecture
  • 連結 34章摘要心得,請先觀看裡面的圖表(重要)

CA Modularization

Vertical Slice

Modular Monolith


各 Package 策略的圖請參考上方連結 34 章摘要心得

Package By Layer

筆者在剛接觸 CA 時有一個很大的迷思是以為 CA Layers 一圈就是一個模組(如果應用程式複雜度不高,確實適用),所以整個應用程式分三個模組。

  • Domain
  • Application
  • Adapter

一開始功能不多時確實運作得很好,隨著功能的增加,出現了一個問題 共用,UseCase 可以操作所有的 Domain 與 Input/Output Port,責任開始變得紊亂(UseCase 知道太多細節)。我們需要一種更能反映業務功能的模組分法,使讓專案能夠重新 Screaming,以下是筆者比較常用的兩個演化方向。

Package By Component

  • 僅提供服務,沒有 UI 操作。
  • 定義 API 以隔離實作細節。

Package By Feature

  • 負責提供使用者互動情境 (垂直切片)。
  • 包含 UI 操作。

筆者在一個應用程式中多是這樣分成以下三類模組

Core Module

  • 一般以 Package By Component 的方式實作。
  • 提供應用程式 共用的服務。

Core 可以是包含業務的 CA 分層,如下圖左邊。 Core 可以是僅將外部服務轉換至內部服務,如下圖右邊。 Core Module

Feature Module

  • 一般以 Package By Feature 的方式實作。
  • 負責提供使用者體驗流。
  • 可以使用 Core 提供的操作,必要時也可以引入所需的外部服務(仍需做 DIP)。

Feature Module

可能會有一個疑問是

UseCase 中使用的介面( Core API )不是 Application 所定義的,這樣的依賴是否為有效 DIP ?

DIP 的重點在於依賴於抽象(穩定),因此只要 Feature 的活動範圍仍在此專案中,依賴 Core API 就是穩定的,外部變化會被擋於 Core 的內部實現中。

實務上甚至可以考慮依賴組織級的 Core Module,是整個部門或者公司所共用的功能,基本上是比較泛用的功能才會這樣使用(聲音/廣告/日誌…)。

App Module

  • 依賴於所有模組。
  • 應用程式的入口。
  • 提供模組間的導航。

App Module