領域驅動設計:CQRS 和事件源的強大功能

筑梦长言發表於2024-07-14

CQRS/ES 如何重新定義構建可擴充套件系統。

在過去的 15 年裡,我一直在深入研究領域驅動設計 (DDD),每一步都在學習和改進。我一直很好奇,尤其是當你深入挖掘時,簡單的客戶請求會變得更加複雜。我特別感謝EventStorming這樣的工具,它幫助揭示看似簡單需求背後的真實流程和事件,不僅讓我,而且讓客戶和領域專家都清楚一切。

大約 10 年前,我首次在業務應用程式中使用了命令查詢職責分離 (CQRS) 和事件源 (ES)。這種方法讓我大開眼界,儘管它確實帶來了挑戰。但是,對我來說,最大的改變之一是意識到 CQRS 如何自然地使資料單向流動。這種單向流動不僅僅是為了保持井然有序;它改變了我們構建、維護和擴充套件系統的方式。這意味著我們可以將更改資料的操作與讀取資料的操作分開。這不僅消除了許多潛在的混亂;它還為我們提供了一種處理複雜系統的直接方法。

雖然我非常喜歡在專案中使用 CQRS/ES,但這並不是成功應用 DDD 的唯一方法。DDD 是一個擁有大量工具和方法的龐大領域,最好的工具和方法實際上取決於您正在從事的工作以及團隊的技能水平。CQRS 非常適合我,尤其是在處理複雜系統時,將讀寫操作分開可以使一切更易於管理。每個專案都是獨一無二的,在很多情況下,其他策略可能是更好的選擇。

CQRS 的好處

但是什麼是 CQRS?這是一個強大的概念。它的核心是將寫入資料(命令)和讀取資料(查詢)的任務分為兩個不同的部分。這種分離旨在明確系統結構、界定職責並提高從系統讀取資料的速度。

我注意到,由於讀寫儲存的嚴格分離,CQRS 經常被視為一種效能最佳化策略。雖然提高效能確實是一個顯著的優勢,但它只是觸及了好處的表面。

CQRS 提供的功能遠不止這些。首先,這種方法為我們提供了一個乾淨、有條理的結構。這種組織結構延伸到領域關注的極佳垂直部分,這意味著我們可以專注於特定領域,而不會迷失在複雜的海洋中。

另一個巨大的優勢是強制單向資料流動。這不僅僅是為了保持資料移動的整潔;它從根本上改變了我們設計和思考系統的方式。它確保我們的資料以可預測的模式移動,減少混亂和錯誤。

CQRS 還促使我們更多地關注行為而不僅僅是資料。這意味著我們在設計系統時會考慮現實世界的行為和後果,避免使用軟體專案中常見的貧血領域模型。貧血領域模型就像沒有肌肉的骨架——它可能擁有所有部分,但無法獨立完成很多工作。CQRS 幫助我們避免這種情況,確保我們的模型具有豐富的行為和功能。

CQRS 中的關注點分離功能使我們能夠輕鬆增強系統檢視。由於讀取模型是分開的,我們可以調整和改進它們,而無需觸及應用程式的核心邏輯。這種靈活性對於不斷髮展的系統來說非常寶貴,可以滿足新的需求或解決新的見解,而無需進行重大改革。

映象資料庫不是 CQRS

我看到一種趨勢,即 CQRS 中的讀寫分離被解釋為擁有兩個具有相同資料模型的映象資料庫,並依靠複製進行同步。然而,這種方法可能錯過了 CQRS 的真正意義。

反模式:映象資料庫不是 CQRS

問題的核心在於,寫入和讀取使用相同的資料模型會導致耦合度過高。CQRS 的優勢在於它允許獨立性,允許寫入端開發豐富的行為驅動模型,而讀取端則針對查詢進行最佳化。跨資料庫映象資料模型會將兩端聯絡得太緊密,從而限制系統的靈活性以及兩端根據需要進行演進的潛力。

此外,這種設定還存在將寫入模型變成圍繞資料庫架構的薄邏輯層而不是健壯的領域模型的風險。它使我們陷入以資料為中心的思維模式,業務邏輯並沒有處於應有的位置 — 嵌入領域本身。

重要的是要理解寫入模型與讀取模型有很大不同。否則,所有的靈活性和能力都會喪失。

使用 CQRS/ES 實現資料行為

對我來說,將 CQRS 與事件源相結合的一個重要好處是,它將焦點轉移到行為上,而不僅僅是資料模型上,從設計上來說就是如此。這種觀點至關重要,因為它使我們的開發工作與我們的軟體旨在代表的現實世界流程和邏輯更加緊密地結合在一起。傳統的開發實踐往往過於強調資料的結構——如何儲存、檢索和修改資料。雖然這種方法很重要,但它也可能導致我們忽視生成和使用這些資料的實際行為和互動。相信我,我見過不止一次這種情況。當 CQRS 與 ES 結合使用時,會扭轉這種關注點。它鼓勵我們圍繞推動變革的業務事件和行動來建模我們的系統,而不僅僅是這些變化影響的資料。

這意味著我們的程式碼以更具表現力的方式反映了業務邏輯。我們不是簡單地在表中插入、更新或刪除行,而是捕獲有意義的業務事件,例如“下訂單”、“使用者建立”或“庫存更新”。這使我們的模型更加豐富和有意義。它提高了我們隨著時間的推移重新思考和改進系統的能力。

CQRS/ES:單向流,有意義的模型。

投影的力量

CQRS 模式最重要的方面之一是投影概念,它本質上是讀取模型的基礎。這種方法對我們在應用程式中處理資料的方式有著深遠的影響,因為最重要的是,它使我們擺脫了與在寫入端表示資料相關的限制。這種分離確保了重點仍然放在準確捕獲行為和域事件上,而不會增加查詢或顯示資料的複雜性。

CQRS/ES 投影 - 以及單向資料流。

讀取端獨立性提供了靈活性,可以根據各種需求定製資料投影。無論是構建資料以實現高效查詢,還是針對特定檢視進行最佳化,投影都可以根據您的需求進行設計。此功能旨在滿足當今的需求,也可以輕鬆調整和擴充套件以滿足未來的需求,而無需觸及現有程式碼。

對於投影,無需修改現有結構或更改寫入端的邏輯。相反,我們可以簡單地建立一個新的、獨立的模組,專門用於根據需要投影和分析資料。這種模組化和可擴充套件性是一個巨大的優勢,使我們的系統能夠有機地發展,而不會損害核心領域邏輯的完整性。

CQRS/ES:從投影檢視資料

結束語

CQRS 與事件源相結合,改變了我們思考和構建軟體系統的方式。透過分離資料的寫入和讀取,我們獲得了一個乾淨、有組織的結構,從而提高了效能和可擴充套件性。更重要的是,這種方法將我們的重點轉移到行為和現實世界的行動上,確保我們的模型功能豐富,並與它們所代表的領域保持一致。投影還允許我們在不觸及現有程式碼的情況下調整和擴充套件我們的系統,這突顯了 CQRS/ES 的靈活性和穩健性。

原文地址:https://ricofritzsche.me/cqrs-event-sourcing-projections/

相關文章