反腐敗層模式

在語意不一致的不同子系統之間建立外觀層或配接層。 此層會轉譯一個子系統對另一個子系統提出的要求。 利用此模式確保對外部子系統的依賴不會限制應用程式的設計。 Eric Evans 首次在《 Domain-Driven Design: Tackling Complexity in the Heart of Software》中描述了這個模式。

內容和問題

大部分的應用程式都依賴其他系統來取得某些數據或功能。 例如,當你將舊有應用程式遷移到現代系統時,該應用程式可能仍會使用現有的舊有資源。 新功能必須能夠呼叫舊版系統。 這項功能對於逐步遷移尤為重要,也就是將較大應用程式的不同功能隨時間遷移到現代系統。

這些舊系統常常存在品質問題,例如複雜的資料架構或過時的 API。 舊有系統所使用的功能和技術,與較現代的系統差異甚大。 若要與舊版系統互通,新應用程式可能需要支援過時的基礎結構、通訊協定、資料模型、API 或其他功能,否則您不會將其放入現代應用程式中。

當你維持新系統與舊系統之間的存取時,你會強制新系統遵守至少部分舊有系統的 API 或其他語意。 當這些舊有功能出現品質問題時,這種支援會破壞原本可能設計得乾淨的現代應用程式。

類似的問題也可能出現在任何開發團隊無法控制的外部系統上。

解決方案

將反損毀層放在兩者之間,以隔離不同的子系統。 此層負責兩個系統間的通訊轉換。 透過這種方法,你可以保持一個系統不變,同時不犧牲另一個系統的設計與技術。

示意圖,展示反貪污層模式的概覽。

下載此架構的 Visio 檔案 。

圖示展示了一個包含兩個子系統的應用。 子系統 A 透過防損層呼叫子系統 B。 子系統 A 與反損毀層之間的通訊一律會使用子系統 A 的數據模型和架構。從反損毀層呼叫子系統 B 符合子系統的數據模型或方法。 反腐敗層包含兩個系統間轉換所需的所有邏輯。 你可以將該層作為應用程式中的元件實作,或作為獨立服務。

問題和考慮

在決定如何實施此模式時,請考慮以下幾點:

  • 防損層會增加兩個系統間通話的延遲。

  • 反腐敗層增加了一項你必須管理和維護的額外服務。

  • 請考慮你打算如何擴展反貪腐層級。

  • 請考慮您是否需要一個以上的反損毀層。 例如,你可能想將功能分解成多個使用不同技術或語言的服務。

  • 考慮你計劃如何管理與其他應用程式或服務相關的防損層,以及如何將其整合進監控、發布與設定流程中。

  • 務必維持並監控交易與資料的一致性。

  • 請考慮反損毀層是否需要處理不同子系統之間的所有通訊,或只是功能子集。

  • 如果反損層是應用程式遷移策略的一部分,請考慮它是永久性的,還是在遷移所有舊有功能後打算將其退休。

  • 前述圖示用不同的子系統來說明這種模式,但你也可以將其應用於其他服務架構,例如單體架構中的舊有程式碼整合。

  • 由於反腐敗層介導可能擁有不同信任等級的系統,因此考慮在此邊界強制執行輸入驗證與淨化。

  • 規劃可觀察性,包括關聯識別碼與結構化日誌,以診斷翻譯失敗。

使用此模式的時機

當下列情況時,請使用此模式:

  • 你計畫遷移分多個階段進行,但同時也需要維持新系統與舊系統之間的整合。

  • 兩個或多個子系統有不同的語意,但它們需要溝通。

在下列情況下,此模式可能不適用:

  • 新舊系統在語意上沒有顯著差異。 在這種情況下,重要的是將反貪腐層聚焦於翻譯邏輯。 避免在此層放置業務規則或流程編排。

工作負載設計

評估如何在工作負載設計中使用反貪腐層模式,以達成Azure Well-Architected框架支柱所涵蓋的目標與原則。 下表提供此模式如何支援每個要素目標的指引。

支柱 此模式如何支援支柱目標
卓越營運有助於透過標準化流程和團隊凝聚力來提供工作負載品質。 此模式有助於確保新的元件設計不會受到舊版實作的影響,當您與這些舊版系統整合時,這些實作可能會有不同的資料模型或商業規則。 它能減少新元件的技術負債,同時仍能支援現有元件。

- OE:04 工具和程式
- OE:07 監視系統

如果此模式在一個支柱內部引入取捨,請將它們與其他支柱的目標進行考量。

Example

此模式具有概念性,源自領域驅動設計軟體開發方法。 像 Azure API 管理 或 Azure Functions 這類 Azure 服務可能會協助協定處理與轉譯,但防損層的核心目的是保護網域模型,而非規定任何特定產品選擇。

以下範例中,API 管理處理外部暴露與協定相關議題。 Azure Functions 透過新系統與舊有系統之間的網域映射來實作防損層。 Azure 監視器 和 Application Insights 提供觀察性,讓你能追蹤兩個子系統間轉換的成功與延遲。

顯示反腐敗層模式之 Azure 概念性實作的圖表。

除了這種同步請求-回應模型外,防損層也可以採用非同步、事件驅動的方法。 透過使用 Azure 服務匯流排、Azure 事件方格 或 Azure 事件中樞,該層將現代網域與舊有系統的吞吐量限制解耦,允許高吞吐量或高度解耦的工作負載進行基於訊息的轉譯。

下一步