Is it a good idea to share valueobjects between domains?

1.2k 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 answers

3
Marius 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.