Is it a good idea to share valueobjects between domains?

1.3k Views Asked by At

Let´s assume we´ve got two domains in a system: Orderdomain and Customerdomain.

Both domains are rather complex and big so merge them into one domain is not an option.

But there is a business relationship between them. On each Order a Customer acts as a Orderer.

I have at least three solutions in my mind.

  1. Store the customerId as a primitive type on both Order and Customer.

  2. Make two valueobjects OrderDomain.CustomerId and CustomerDomain.CustomerId. Make sure these type types can be compared for equality.

  3. Make a third component "SharedValueObjects" with a valeobject CustomerId and use that type in both Domains

Which one is preferred or can you come up with a forth better one?

1

There are 1 best solutions below

3
On

I'll try to answer both your general question about value objects and the more specific one from your comments?

  1. Can domains share value objects?

It depends. In the system I currently work on we have 15 or so large scale services, we share value types like "EMailAddress", "PhoneNumber", "Money", etc. These types are well-defined and we have no sharing issues, but I wouldn't share stuff just because they might be used somewhere else, savour your shared value-types to the ones who are actually used. When sharing you pay the price of system-wide coupling.

  1. Would I expose the relationship between a customer an a order as a value object wrapping the key?

No I would not, as others has pointed out, Customer is something that someone who is working in the order-domain would know about and require data from. If you claim that "Customer" and "Order" represents two different domains than I am assuming that the "Customer"-domain is something like CRM-data? If you are modelling "Customer" and "Order" separately than the "Customer"-domain can not contain the data which you require in your "Order"-domain, lets say for example a billing address. I understand your objection against tight coupling and huge object graphs, but you can handle this by making sure that you allow multiple "Customer"-entities in your system; each "Customer" representing its own set of data and behaviour within a bounded contex. For example, you can have both a Customer entity in your CRM-domain and a Customer entity in your "Order"-domain (I guessing its really a Ordering-domain, because "Order" sounds like an entity not an encapsulated set of business processes). In your CRM-domain the customer might have stuff like, phone numbers, contact persons, postal addresses, etc), in the "Order"-domain your customer will certainly have orders, and stuff like a billing address, etc. So to summarize: don't create a customer-which-has-everyting, put that in its own domain and remove the relationship to orders, you are only reducing the size of your object graph.