Multiple Aggregates in Same Module
In the same module, it's normal for many related aggregates to appear. When business is known to iterate rapidly, if we still write like a running account without extra consideration for variable relationships, the code will soon become hard to maintain.
Recommended: Define Different "Constant Pools" by Business
Assume Order and Book aggregates have very close business relationships. Here's the code:
const d = createDomainDesigner()
const i = d.info
const UpstreamSystem = d.system('UpstreamSystem', 'Upstream system')
// Book "constant pool"
const bookValues = {
ISBN: i.id(
'isbn',
`International Standard Book Number
This value serves as an id and can uniquely identify a book`
),
bookName: i.valueObj('bookName', 'Book name'),
seriesName: i.valueObj('seriesName', 'Series name'),
bookPrice: i.valueObj('bookPrice', 'Book price'),
}
// Order "constant pool"
const orderValues = {
orderSequence: i.id(
'orderSequence',
`Order serial number
This value serves as an id, determined during requirements research`
),
globalSequence: i.valueObj(
'globalSequence',
d.note`Global sequence number
During requirements research, it was determined that this value is uniformly generated by an ${UpstreamSystem} interface`
),
bookSets: i.func(
'bookSets',
[bookValues.ISBN, bookValues.bookPrice, 'count'],
'Order collection'
),
}
const BookPutInStorage = d.event('BookPutInStorage', [bookValues.ISBN], 'New book put in storage')
const PutBookInStorage = d.command(
'PutBookInStorage',
[bookValues.ISBN, 'time'],
'Put book in storage command'
)
const BookAgg = d.agg(
'bookAgg',
[bookValues.ISBN, bookValues.bookName, bookValues.seriesName],
'Order aggregate'
)
const OrderAgg = d.agg(
'OrderAgg',
[i.func('Product collection', [bookValues.ISBN])],
'Order aggregate'
)In this code snippet, we define two constant pools: bookValues and orderValues. Put values that need reuse into them, and other nodes can take from here when defining the same values.
Benefits of this approach:
No repetitive definitions. If defined every time
This "constant pool" also serves as a glossary. For terms that aren't easy to understand or that team members might interpret differently, we can describe them in detail here
Flexibly Use TypeScript's Module Mechanism
Assume the Order aggregate depends on the Book aggregate. Code can be split like this:
import { d } from './order-detail/common'
import './order-detail/book'
import './order-detail/order'
export default dimport { d, i } from './common'
import { bookValues } from './book'
const OrderPlaced = d.event(
'OrderPlaced',
[i.id('orderSequence', 'Order serial number'), bookValues.ISBN],
'Order placed'
)import { d, i } from './common'
export const bookValues = {
ISBN: i.id('isbn', 'International Standard Book Number'),
}
const BookAgg = d.agg(
'bookAgg',
[
/* ... */
],
'Book aggregate'
)import { createDomainDesigner } from '@ddd-tool/domain-designer-core'
export const d = createDomainDesigner()
export const i = d.info