Sunday, November 04, 2007

Evolving Coordination Layer

I've posted about this before but on my project we have a coordination layer that sits above the domain but I thought I'd add another post about it.

Since a coordination layer is quite closely linked to a domain assembly we have more than one of them, so if we had two domain models our projects would be:

  1. Company.Customers.Domain
  2. Company.Customers.Domain.Coordination
  3. Company.Customers.Peristence
  4. Company.Finance.Domain
  5. Company.Finance.Domain.Coordination
  6. Company.Finance.Peristence
This gives me a lot of flexibility. For example our Finance domain has a reference to our Customers domain but there is no reference going the other way (at all). This is the way we want it but we have a process where by to create a Customer you must already have a saved CustomerCreditCheckRequest object from the Finance assembly, we put that logic into a CustomerCreationService in the Coordination layer. This service would be very short and its form would be:
  1. Create the Customer by calling into a CustomerFactory within the Customer domain assembly.
  2. Create a CustomerCreditCheckRequest and associate it with the new Customer before saving it. This logic obviously calls off to a repository and to the Finance domain and so cannot go into Company.Customers.Domain.
  3. Return the Customer.
The class names are all made up but you see my point, and note that all the interesting domain domain logic is kept within CustomerFactory. It does mean the coordination layer is quite highly coupled (in this case to Finance) but if that becomes a problem we can deal with it (interfaces and injection), and for now it doesn't seem to me to be at all important.

When Is A Domain Service Enough?

There is another "issue", what do if we already have a coordination layer service and no domain service and want to decide where to put some code. For example lets say Order/Customer aggregates are in a single domain assembly but a rule is that for an Order to become active we must ensure the Customer has a valid Address. This is a cross aggregate rule but we could enforce it in a domain service, there is no specific need for the coordination layer to be involved. So we could have an OrderActivationService in the domain, however we already have an OrderService in the coordination layer...do we put the code in there instead?

Although I originally thought of just putting the cross aggregate logic in the domain I've been swayed by a colleague and of course even we could put a call to the OrderActivationService (domain) inside a suitably named method in the OrderService, keeping the logic in the domain but giving a simple single class interface to the GUI.

Compared To Service Layer

Evan Hoff did point out that this layer could be mistaken for a Service Layer, the links is here. As we discuss they are quite different as the coordination layer is not responsible for things like email/transactions/session management and is very closely linked to the domain itself. Not to say we might not also need a service layer at some stage, or that the coordination layer might not become one in time...

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

1 comment:

  1. Anonymous9:04 pm

    Due to the groups name change, the link to the discussion with Evan is now here

    ReplyDelete