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:
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
Customerthen 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 aCustomerin your own, say,OrdersBC then you'll have either only theCustomerIdor aCustomervalue 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
CustomerProfilein yourOrdersBC where you have some BC-specific data such as customer level (Gold, Silver, Bronze, etc.). You could have theIdof 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 aCustomerIdthat 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
Invoicefrom a supplier and you register it in your system. You'll probably have your own invoice with all relevant data which includes anExternalReferencewhere you'd store theInvoiceNumberreceived from the supplier.To answer you question as to whether there is anything wrong with having your own
Customerin 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. TheFinanceBC maintains the asset register and keeps track of depreciation. TheMaintenanceBC cares about work orders and general maintenance of the seat. TheEventsBC 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 calledSeatin any of the BCs. TheFinancefolks would call it anAsset, theMaintenancefolks would perhaps call itComponent, and theEventsfolks may call it aBookableItem(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. TheEventsBC would then mark that seat asUnavailable. 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.