軟體架構中的邊界(Boundaries)並非只有一種形式。
它們可以發生在不同層次,從編譯期的原始碼隔離,到執行期的網路隔離。
一個複雜系統往往會混合使用多種邊界策略。

一、跨越邊界的機制:多型的魔法#

在討論不同形式前,須先理解「跨越邊界」的核心機制。 無論邊界是透過函式呼叫還是網路封包,管理重點都在於:原始碼的依賴關係

我們用 動態多型(Dynamic Polymorphism) 管理這種關係:

  1. 一般情況(Low ➡️ High):

    • 低層級客戶端呼叫高層級服務。
    • 執行期(Runtime)方向與編譯期(Compile-time)依賴方向相同
  2. 關鍵架構(High ➡️ Low):

    • 高層級業務邏輯需呼叫低層級細節。
    • 依賴反轉: 透過介面多型,執行期控制流是 High ➡️ Low
      但編譯期依賴方向被反轉為 Low ➡️ High(低層實作依賴高層介面)。

二、四種邊界策略#

Uncle Bob 分析了四種從「緊密」到「鬆散」的邊界形式:

邊界類型定義通訊方式特點
單片
(Monolith)
同處理器、同位址空間函式呼叫速度快、成本低;
透過原始碼層級區分
部署元件可獨立部署的二進位檔
.jar, .dll
動態鏈結不涉及重新編譯;
可抽換元件
本地行程同處理器、
不同位址空間
Socket、
共享記憶體、IPC
透過配置或註冊表
尋找彼此
服務
(Services)
不同主機上運行網路封包最強邊界;
需考慮延遲問題

服務層級的外掛概念#

即便在服務層級,我們依然應用 Plugin 架構

  • 錯誤觀念: 服務就是把功能切開就好
  • 正確觀念: 低層級服務應被視為「插入」到高層級服務中的外掛。
    高層服務不應包含低層服務的具體知識

管理程式運行時的跨越邊界(跨端呼叫函式),本質就是管理原始碼的依賴關係
這關乎當某個模組改變時,哪些相依模組需更改或重新編譯。

良好架構會讓系統邊界混合使用這些策略(本地通訊 + 網路邊界),
以達到最佳的效能與維護性平衡。