Following this answer from different question I've been somewhat shocked with the following statement:
An aggregate in one BC would be represented either by an id or as a value object in another BC. Only a single BC should be the system of record of any aggregate.
What I do agree with, is the fact, that only one BC should be the owner of the given identity (the initiator of that identity presence in the whole system). But what is confusing to me, is the statement, that every other BC should represent the same concept only as a read only value object with just the subset of the attributes of the entity from BC that owns the given identity (no extra attributes related to consuming BC).
Using a Customer as an example, what's wrong with representing it as an entity in multiple BCs with different attributes in each BC (especially, when there's some BC related, user editable config, which wouldn't make sense in another BC at all), but sharing the same identity? I tought, that this is the essence of the bounded context definition - to represent the same concept (same real world identity) in different domains with the behavior and attributes only related to that given domain. Am I missing something? Is it better to use single BC for CustomersManagement with all possible attributes (user editable config) that all other BCs could use?
I may be stating some obvious bits here, but please bear with me as I put it all together.
The following statement refers only to the aggregate itself, not the identity:
An aggregate in one BC would be represented either by an id or as a value object in another BC. Only a single BC should be the system of record of any aggregate.
The main concept here is that a particular aggregate root has a single system of record. This idea isn't unique to domain-driven design. Traditionally, a database record would also only have a single source of truth.
When it comes to the identifier of an aggregate, or record, it can literally be anything unique.
If you have a Customer
then the system of record is probably your CRM system and any and all changes related to data that is maintained by the CRM system should only ever be changed there. If you need to have a Customer
in your own, say, Orders
BC then you'll have either only the CustomerId
or a Customer
value object that contains some minimal data that is, still, maintained in the CRM system. You wouldn't ever make changes to the data in your BC that is maintained in the CRM system; else they are immediately out of whack, and trying to replicate data back up-stream isn't only painful, but it is usually not a good idea (multiple conflicting updates from downstream systems, for instance). If you only have the customer id then you'd need to ask the CRM system, probably via and API of sorts, for any additional data. That is a design choice. Copies of data would need to kept up-to-date and messaging / event-driven architectures are useful here.
Now, if you'd like to relate any data to a particular customer in your own BC then you are creating a new aggregate in your BC that is related to the customer, but your BC is the system of record for that data. How you end up relating it is, again, a design choice. Let's go with a CustomerProfile
in your Orders
BC where you have some BC-specific data such as customer level (Gold, Silver, Bronze, etc.). You could have the Id
of that profile simply be the same id from the CRM system, or you could map it. Perhaps there are different profiles based on some type and the profile has its own id but still also has a CustomerId
that it is linked to.
This is something that isn't uncommon and is a form of a weak reference that one typically finds across systems. For instance, you receive an Invoice
from a supplier and you register it in your system. You'll probably have your own invoice with all relevant data which includes an ExternalReference
where you'd store the InvoiceNumber
received from the supplier.
To answer you question as to whether there is anything wrong with having your own Customer
in different BCs, there isn't necessarily anything wrong with it as long as it fits into the ubiquitous language of the domain experts. I've used the example of a seat in a stadium. The Finance
BC maintains the asset register and keeps track of depreciation. The Maintenance
BC cares about work orders and general maintenance of the seat. The Events
BC cares about booking the seat for events. Each of these have their own view of the physical seat and they have different behaviours, and chances are that they are not event called Seat
in any of the BCs. The Finance
folks would call it an Asset
, the Maintenance
folks would perhaps call it Component
, and the Events
folks may call it a BookableItem
(such as a seat, or a bicycle, or a VIP suite). However, when the maintenance department removes a seat for repairs it will need to publish an event notifying any interested parties. The Events
BC would then mark that seat as Unavailable
. All these BCs would need to know about the seat and have a common identifier, probably the one in the asset register.
I hope I understood your question/concern correctly.