適應變化 - AWS 規範指引

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

適應變化

軟件系統往往變得複雜。造成這種情況的原因之一可能是頻繁變化的業務需求和很少的時間來相應地適應的軟件體系結構。另一個原因可能是在項目開始時建立軟件架構以適應頻繁變化的投資不足。無論是什麼原因,軟件系統都可能會變得複雜到幾乎不可能進行更改的程度。因此,從項目開始構建可維護的軟件體系結構非常重要。良好的軟件架構可以輕鬆適應變化。

本節介紹如何通過使用容易適應非功能性或業務需求的六角形架構來設計可維護的應用程序。

使用連接埠和介面卡,適應新的非功能性需求

作為應用程序的核心,域模型定義了從外部世界滿足業務需求所需的操作。這些動作是通過抽象,這被稱為端口定義。這些連接埠由不同的介面卡實作。每個介面卡都負責與另一個系統的互動。例如,您可能有一個適配器用於資料庫儲存庫,另一個適配器可與第三方 API 互動。網域並不知道介面卡的實作,因此很容易用另一個介面卡取代一個介面卡。例如,應用程式可能會從 SQL 資料庫切換到 NoSQL 資料庫。在這種情況下,必須開發一個新的適配器來實現由域模型定義的端口。該域對數據庫存庫沒有依賴關係,並使用抽象進行交互,因此不需要更改域模型中的任何內容。因此,六角形架構輕鬆適應非功能性要求。

使用命令和命令處理常式來適應新的業務需求

在傳統的分層架構中,域取決於持久層。如果您想要變更網域,您也必須變更持續性層。相比之下,在六角形體系結構中,域不依賴於軟件中的其他模塊。該域是應用程序的核心,所有其他模塊(端口和適配器)都取決於域模型。該域使用依賴反轉原則通過端口與外部世界進行通信。依賴反轉的好處是,您可以自由更改域模型,而不必害怕破壞代碼的其他部分。因為網域模型反映了您嘗試解決的商業問題,因此更新網域模型以適應不斷變化的業務需求並不是問題。

當你開發軟件時,關注點的分離是一個重要的原則要遵循。若要實現此分隔,您可以使用稍微修改的指令模式。這是一種行為設計模式,其中完成操作所需的所有信息都封裝在命令對象中。然後,命令處理常式會處理這些作業。命令處理常式是接收命令、改變網域狀態,然後將回應傳回給呼叫者的方法。您可以使用不同的用戶端 (例如同步 API 或非同步佇列) 來執行命令。建議您針對網域上的每項作業使用命令和命令處理常式。透過遵循這個方法,您可以透過引入新的命令和命令處理常式來新增功能,而不需要變更現有的商務邏輯。因此,使用命令模式可以更輕鬆地適應新的業務需求。

使用服務外觀或 CQRS 模式來解耦元件

在六角形架構中,主要介面卡負責將來自用戶端的傳入讀取和寫入要求鬆散耦合到網域。有兩種方法可以實現這種鬆散耦合:使用服務外觀模式或使用命令查詢責任隔離(CQRS)模式。

服務外觀模式提供前端介面,為客戶提供服務,例如表示層或微服務。服務外觀為用戶端提供數個讀取和寫入作業。它負責將傳入的請求傳輸到域,並將從域接收到的響應映射到客戶端。對於具有單一責任的微服務而言,使用服務外觀很容易進行多項操作。但是,在使用服務外觀時,很難遵循單一責任和開放式封閉原則。單一責任原則指出,每個模組都應該對軟體的單一功能負責。開閉原則指出,代碼應該是開放的擴展和關閉進行修改。隨著服務外觀的擴展,所有操作都收集在一個接口中,更多的依賴關係被封裝到其中,更多的開發人員開始修改相同的外觀。因此,我們建議您使用服務外觀,只有在很明顯的情況下,該服務在開發過程中不會延長很多時間。

在六角形架構中實作主要配接器的另一種方法是使用 CQRS 模式,該模式會使用查詢和命令來分隔讀取和寫入操作。如前所述,命令是包含變更網域狀態所需之所有資訊的物件。命令是由命令處理常式方法執行的。另一方面,查詢不會改變系統的狀態。他們唯一的目的是將數據返回給客戶。在 CQRS 模式中,命令和查詢在單獨的模塊中實現。這對於遵循事件驅動架構的專案尤其有利,因為命令可以實作為以非同步方式處理的事件,而查詢則可以使用 API 同步執行。查詢也可以使用針對其進行最佳化的不同資料庫。CQRS 模式的缺點是,實施比服務外觀需要更多的時間。我們建議您對計劃長期擴展和維護的專案使用 CQRS 模式。命令和查詢提供了一種有效的機制,用於應用單一責任原則和開發鬆散耦合的軟件,尤其是在大型項目中。

從長遠來看,CQRS 有很大的好處,但需要初始投資。因此,建議在決定使用 CQRS 模式之前仔細評估您的專案。但是,您可以直接從一開始就使用命令和命令處理常式來構建應用程式,而不需分隔讀取/寫入作業。如果您決定稍後採用該方法,這將幫助您輕鬆地為 CQRS 重構項目。

織檢視

六角形架構、領域導向設計和 (選擇性) CQRS 的組合,可讓您的組織快速擴充產品規模。根據康威定律,軟件架構傾向於發展以反映公司的通信結構。這種觀察歷史上有負面的含義,因為大型組織通常根據技術專業知識(例如數據庫,企業服務總線等)來構建團隊。這種方法的問題在於,產品和功能開發始終涉及交叉問題,例如安全性和可擴展性,這需要團隊之間的持續溝通。基於技術特徵的組織結構化團隊會在組織中創建不必要的孤島,從而導致溝通不良,缺乏所有權並失去了大局。最終,這些組織問題反映在軟件架構中。

另一方面,逆康威機動定義基於促進軟件體系結構的領域的組織結構。例如,跨職能專案團隊會負責一組特定的有界前後關聯,這些前後關聯是使用 DDD 和事件風暴來識別。這些有界的前後關聯可能會反映產品的非常特定的功能。例如,客戶小組可能負責付款內容。每個新功能都會分配給一個具有高度凝聚力和鬆散耦合責任的新團隊,因此他們只能專注於該功能的交付,並縮短上市時間。可以根據圖徵的複雜性調整團隊的比例,因此可以將複雜的特徵指定給更多的工程師。