基于DDD和CQRS思想而開發的一個領域驅動框架:Aggregate Framework
1. Aggregate Framework概述
Aggregate Framework是基于DDD和CQRS思想而開發的一個領域驅動框架。其主要目標是方便開發人員運用DDD和CQRS思想來構建復雜的、可擴展的應用系統。該框架提供了最核心的構建塊的實現,比如Aggregate、Repository和Event。此外,該框架支持與Spring集成,提供使用 annotation的方式讓開發人員方便地注冊事件及定義事件處理,使用Spring事務管理器管理事務時,支持Unit Of Work模式存儲數據。
2. 核心概念
2.1 Aggregate
Aggregate(聚合)定義了一組具有內聚關系的相關對象的集合,是一致性修改數據的單元。聚合里包含有聚合根,實體、值對象。在 Aggregate Framework中,聚合最核心的接口是DomainObject,聚合對象都實現該接口。另一個接口是AggregteRoot,該接口繼承自 DomainObject, 聚合根實現該接口。AbstractDomainObject抽象類實現了DomainObject接口,并提供了對部分方法的重載。 AbstractAggregateRoot繼承AbstractDomainObject,在AbstractDomainObject上新增了對 Event的支持。為方便定義聚合對象,AbstractSimpleAggregateRoot和 AbstractSimpleDomainObject分別對AbstractAggregateRoot和AbstractDomainObject進行了簡單實現,提供對接口的默認實現,讓開發人員不需關系內部事件注冊及發布機制。
2.2 Repository
在Repository構建塊中,最核心的接口莫過于Repository。它是個標記接口,CrudRepository繼承該接口,并為聚合對象提供了專門的CRUD方法。AggreateRepository繼承CrudRepository, 限制操作的實體是聚合根。AbstractAggregateRepository提供了對AggregateReposiotry的部分實現,將事件的發布進行了簡單處理。TraversalAggregateRepository繼承了AbstractAggregateRepository,同時實現了對聚合里對象的成員變量進行遍歷并調用對應的DAO方法進行CRUD操作。DaoAwareAggregateRepository繼承自 TraversalAggregateRepository,實現了基于Spring獲取DAO依賴實現聚合對象的遍歷CRUD操作。
2.3 Event
Aggregate Framework里有兩種事件,一個是Domain Event,另一個是Application Event。Domain Event表達業務上的事件,而Application Event是系統層面的事件。當有事務支持時,Domain Event在事務邊界內發布,而Applicatin Event在事務結束后發布。AggregateRoot接口里定義了兩個方法,一個是applyDomainEvent,用來注冊Domain Event, 另一個時applyApplicationEvent,用來注冊Application Event。
3. 使用Aggregate Framework開發示例
示例通過對一個聚合的操作及事件處理來闡述,代碼可以參考aggregate-framework-test項目。該聚合模型里 Order是聚合根,SeatAvailability和Payment為聚合里的實體,Order與SeatAvailability是一對多關系,與 Payment是1對1關系,為了闡述問題,SeatAvailabilit引用了Payment以示例聚合內對象相互引用。
3.1 定義領域模型
Order繼承AbstractSimpleAggregateRoot, 其聚合了seatAvailabilities和payment。在seatAvailabilities上添加DaoAwareQuery annotation表示當需要根據Order的主鍵獲取對應的SeatAvailability實體時需要調用SeatAvailabiltiy對應 DAO的哪個方法。SeatAvailablity聚合了payment,在一個聚合中,SeatAvailability引用的payment與 Order引用的payment可以是同一個。
3.2 定義Repository
OrderRepository繼承DaoAwareAggregateRepository,并定義操作的AggregateRoot實體類型為Order。
3.3 定義聚合對象的DAO
每個聚合對象都有一個對應的DAO。聚合根的DAO為OrderDao,繼承AggregateRootDao, SeatAvilability和Payment的Dao繼承DomainObjectDao。
3.4 定義事件及處理
示例中定義了三個事件:OrderCreatedEvent,OrderUpdatedEvent,OrderUpdatedApplicationEvent。 OrderCreatedEvent和OrderUpdatedEvent被applyDomainEvent注冊,表示領域事件,OrderCreatedEvent在Order初始化時注冊,OrderUpdatedEvent則在updateContent里注冊。 updateContent里還使用applyApplicationEvent注冊了OrderUpdatedApplicationEvent,表注冊的事件為系統事件。使用Spring管理并將aggregate-framework-context.xml載入Spring后,標識了 EventHandler annotation的方法將自動為事件處理方法,其對應的事件與方法入參類型對應。示例中OrderHandler為事件處理類,handleOrderCreatedEvent、handleOrderUpdatedEvent、 handleOrderUpdatedApplicationEvent分別處理OrderCreatedEvent、 OrderUpdatedEvent和OrderUpdatedApplicationEvent事件。
3.5 事務支持
在調用Repository方法時,可以選擇事務以實現聚合的原子化操作。使用Spring管理事務時,需配置SessionDataSourceTransactionManager為事務管理器。
3.6 Test
最后在aggregate-framework-test項目里,OrderRepositoryTest里有各種unit test。