Let's say I have two bounded contexts, the Shipping Context and the Billing Context. Each of these contexts need to know about the customer.
At a data level, the customer is represented by a CustomerTbl
table in a database. This table consists of all the necessary columns that describe the customer.
Columns in CustomerTbl
(simplified):
Name
PhysicalAddress
PaymentMethod
The Shipping Context is concerned with Name
and PhysicalAddress
while the Billing Context is concerned with Name
and PaymentMethod
.
In the Shipping Context I have modeled the aggregate Recipient
:
Recipient
now has properties/value objects for Name
and PhysicalAddress
In the Billing Context I have modeled the aggregate Payer
:
Payer
has properties/value objects for Name
and PaymentMethod
Both Recipient
and Payer
aggregates are completely separated by the context boundary. They also have their own repositories.
Is it acceptable to have multiple aggregates (provided that they are in separate bounded contexts) using the same "database table"?
Customer data would likely be needed in many more bounded contexts. Would this not mean many aggregate, repository and factory implementations for each bounded context? There will be a degree of redundancy in code. Does this not effect maintainability?
Is it acceptable to have shared properties across aggregates? An example would be the customer Name
property. This would also mean redundant validation code?
1) Is it acceptable to have multiple aggregates (provided that they are in separate bounded contexts) using the same "database table"?
2) Customer data would likely be needed in many more bounded contexts. Would this not mean many aggregate, repository and factory implementations for each bounded context? There will be a degree of redundancy in code. Does this not effect maintainability?
Not necessarily, have a look at the shared kernel pattern.
3) Is it acceptable to have shared properties across aggregates? An example would be the customer Name property. This would also mean redundant validation code?
Same answer as question 1. Concerning redundancy, once you have a shared kernel you may simply put your validator classes in there.
Elegant code does not unnecessarily put great design principles at odds with each other. Usually there is a way that satisfies the principles. You simply haven't found it yet, because either you don't understand the principles enough or you haven't dissected your problem enough.
(if this sounds dogmatic that is because software engineering is actually a religion)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With