17

領域驅動設計學習筆記(19):DDD需要套用Unit of Work (UoW) 設計模式嗎?

 3 years ago
source link: https://teddy-chen-tw.blogspot.com/2021/08/19dddunit-of-work-uow.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

領域驅動設計學習筆記(19):DDD需要套用Unit of Work (UoW) 設計模式嗎?

August 19 22:56~August 20 00:29

AM-JKLX-K6M6ntbUE3KndFhcTnWwf1wm7sz-KMExwQBwmCsM9_lBMDwrG0sZWJ8YEsL4oG2uNvOVS9d_Twk1okvpqTH42cajLRlav8Tlc2KaIYX-L-pAjURgFFWElQa1CDE7QZgs9OufG0U0YUW-OPNMNNewVQ=w1484-h220-no?authuser=0

背景說明

昨天Teddy在【搞笑談軟工Facebook社群】提到在DDD中應該是不需要使用Unit of Work (UoW) 設計模式,鄉民A問在DDD不合適使用UoW的原因是什麼?今天談一下這個問題。

Unit of Work設計模式

依據Martin Fowler在《Patterns of Enterprise Application Architecture》的解釋,Unit of Work:

Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolutions of concurrency problem. (Google 翻譯:維護受業務交易影響的物件列表,並協調更改的寫入和並發問題的解決方案。)

感覺有一點抽象,Teddy舉一個ezKanban系統的例子來說明Unit of Work。

範例說明:ezKanban與看板遊戲

ezKanban是一個採用DDD與Clean Architecture架構所開發的線上同時多人使用看板系統,圖1展示ezKanban的五個使用案例:Create Board、Create Workflow、Create Stage、Create Swimlane、Crate Card。其中Create Board操作Board Aggregate,Create Card操作Card Aggregate,另外三個使用案例則是操作Workflow Aggregate。

AM-JKLUreQ7_6crMISqgiG3rCKfrOkPZ4bkXQCasmIIX1nIz5PIOENqF-0C9y7mcvqjXvp6715pSClkSWmVP-d24IEiMd4YC0-sdqvAtEAOCAwJbV94eaSSnzQVUOMfIeemdjHfaQ3fW4LKc1hBzgSdQ7N5phw=w1024-h1394-no?authuser=0

由於在DDD中Aggregate就是一個交易邊界(transaction boundary),所以每一個使用案例都在各自的交易中處理。從這個角度來看,Aggregate本身就已經是Unit of Work,如果還需要額外套用Unit of Work,就代表有某種需求,需要在Aggregate之外再加上一層,把多個Aggregate放在一個更大的Unit of Work。

最近Teddy與ezKanban團隊使用ezKanban系統開發一個新的看板遊戲功能,新寫了Create Kanban Game這個使用案例,請參考圖2。

AM-JKLViS12TbMxutXUrT6XCXrRvOTAR5CJLi7ygSdGIKBAvy5vKKagMKCPW3ZvO8Nqhq-6UoN4dQxMETiRwD91ocC1B3kHwH1xpj3urceUkuZP6xsJmffFHWj8HFJAhfVAMck4LfP2KMrIkgqqfGL0_9UPqDQ=w1246-h1122-no?authuser=0

Create Kanban Game的實作方式只是呼叫原本寫好的那五個使用案例,此時有鄉民可能會認為:「是不是應該把Create Board、Create Workflow、Create Sage、Create Swimlane、Create Card放在同一個交易中處理以便確保資料的一致性?」如果真的要這麼做,就有可能套用Unit of Work設計模式。

Unit of Work是把原本不同的工作放在同一個交易(transaction)來處理,這在傳統的CRUD系統(集中式系統)是很常見的需求。但是,在DDD中,不同的Aggregate是透過領域事件(domain event)達到狀態的「最終一致性」(eventual consistency),而不是將這些不同的Aggregate放在另一個Unit of Work中達到ACID。

在DDD中,如果你願意,Aggregate是可以變成一個最小的部屬單位,也就是說Board、Workflow、Card可能被部署成微服務,因此自然也不適合將它們放在同一個Unit of Work(同一個交易)來處理。

如果是同一個Aggregate…

後來鄉民B進一步問:「如果是在同一個Aggregate的話,是不是就可以套Unit of Work?」

例如,假設在ezKanban系統中有一個使用情境是要一次新增一百張卡片,實作方式如果是連續呼叫Create Card 使用案例一百次,這樣都是操作同一個Card Aggregate,是不是就可以把這些對於Create Card使用案例的一百次呼叫放在Unit of Work中?

如果是這種需求,乍看之下覺得要用Unit of Work是很合理的。但是,再仔細思考一下,在DDD中「Aggregate形成交易邊界」這個特性,雖然都是相同型別的Aggregate(都是Card),但這一百張卡片是一百個不同的aggregate instance,所以嚴格講起來每一個aggregate instance應該都只管自己的交易。

但是,這樣一來「資料正確性」怎麼辦?Teddy覺得在DDD這頂「大帽子」之下,應該儘量朝向分散式處理、最終一致性、交易補償(錯誤處理)的角度來思考系統的行為與狀態,長期而言會比較能夠得讓系統從分析、設計到實作,保持一致性與完整性

一旦在DDD裡面採用「Unit of Work將多個Aggregate打包處理」,Teddy大膽假設團隊中就會有人的想要在DDD中做到「分散式交易處理」或是「二段式提交(Two-Phase Commit)」的效果,如此一來思考模式又回到傳統的ACID與集中式系統的模式。

那麼,回到根本的問題,為什要要DDD勒?

友藏內心獨白:沒有一定不行,真的想用就用,用了也不用有警察來開罰單。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK