再讀整潔架構之道(六)邊界

Tommy Cheese | · 閱讀約需 3 分鐘

什麼是邊界

軟體架構設計本身就是一門劃分邊界的藝術。

邊界的作用是將軟體劃分為各種元素,以便約束邊界兩側的依賴關係。在專案初期劃分的邊界可以方便我們將一些決策儘量延後進行,確保未來這些決策不會對系統額核心業務邏輯造成干擾。劃分邊界同時可以降低或消除架構中不必要耦合,系統中存在的耦合——尤其是那些過早做出的、不成熟的決策所導致的耦合(如採用的框架,資料庫等元素,這些細節應該被推遲)是系統最消耗人力資源的部分。

那麼如何劃分邊界呢?可以遵循如下的基本原則:

  • 邊界應該劃分在那些無關的事情中間:如 GUI 與業務邏輯,這意味著輸入輸出(GUI)對於業務邏輯來說並不重要,業務邏輯可以選擇多種不同的 GUI 實現;
  • 邊界線應該沿著系統的變更軸來畫。也就是說,位於邊界線兩側的元件應該以不同原因、不同速率變化著。指導變更軸心的原則包括模組/類級別的SRP原則和元件級別的CCP原則。

在瞭解劃分邊界的重要作用,並且瞭解如何劃分邊界後,可以進一步探討該如何劃分邊界了,即劃分邊界的基本流程:

  1. 首先將系統分割成元件,其中一部分是系統的核心業務邏輯元件,另一部分是與核心業務無關但負責提供必要功能的外掛;
  2. 通過對原始碼的修改,讓這些非核心元件依賴於系統的核心業務邏輯元件;

劃分邊界是一種對依賴反轉原則和穩定抽象原則的具體應用,依賴剪頭應該由底層具體實現指向高層抽象的方向。

邊界剖析

一個系統的架構是由一系列軟體元件以及它們之間的邊界共同定義的

邊界具有多種形式,本章以跨邊界呼叫為例來剖析邊界。

在執行時,跨邊界呼叫指的是邊界線一側的函式呼叫另一側的函式,並同時傳遞資料的行為。構造合理的跨邊界呼叫需要我們對原始碼中的依賴關係進行合理管控,若不對依賴管控,可能導致一個模組的原始碼發生變更時,其他模組的原始碼也可能會隨之發生變更或重新編譯,並需要重新部署,劃清邊界有助於減少這種情況的發生。

跨邊界呼叫包含不同的類別:原始碼層次、部署層次、服務層次以及物理邊界。

原始碼層次的跨邊界呼叫

原始碼層次的跨邊界調用出現在單體架構中,這類架構一般都需要利用某種動態形式的多型來管理其內部的依賴關係。

最簡單的跨邊界呼叫形式,是由低層客戶端來呼叫高層服務函式,這種依賴關係在執行時和編譯時會保持指向一致,都是從低層元件指向高層元件。

(原示意圖暫缺)

但當高層元件中的客戶端需要呼叫低層元件中的服務時,我們就需要運用動態形式的多型來反轉依賴關係(圖中的Service介面是某種形式的SPI)。

(原示意圖暫缺)

部署層次的跨邊界呼叫

部署層次的跨邊界呼叫將其所有可部署的單元打包成一個便於操作的檔案格式,除這一點以外,這種按部署層次解耦的元件與單體結構幾乎是一樣的。

部署層次的跨邊界呼叫涉及到物理邊界,因為不同部署的單元需要跨越物理邊界來完成通訊。常見的物理邊界包括動態連結庫、執行緒、本地程序等。

服務層次的跨邊界呼叫

服務是系統架構中最強的邊界形式,一個服務就是一個程序。在劃分架構邊界時,一定要儘可能地控制通訊次數。在這個層次上通訊必須能夠適應高延時情況。除此之外,我們可以在服務層次上使用與本地程序相同的規則。也就是讓較低層次服務成為較高層次服務的“外掛”。

comments powered by Disqus