Domain Model Service
Recent activity on the Domain-Driven Design user group made me decide to share this writing dating November 2005.
Almost a year ago someone asked me whether I have read Domain-Driven Development (DDD) and if so, what a typical service on top of a rich domain model could look like. After giving it some thought I failed to come up with a crystal clear answer. Discussing my ideas with Stefan Nijenhuis culminated in a confusion of tongues. This eventually led to the name of this article in which we both felt comfortable.
Let's see what others have to say about this topic:
Eric Evans: Some concepts from the domain aren’t natural to model as objects. Forcing the required domain functionality to be the responsibility of an Entity or Value either distorts the definition of a model-based object or adds meaningless artificial objects. When a significant process or transformation in the domain is not a natural responsibility of an Entity or ValueObject, add an operation to the model as a standalone interface declared as a Service. Define the interface in terms of the language of the model and make sure the operation name is part of the UbiquitousLanguage. Make the Service stateless. DDD Services
Martin Fowler: Enterprise applications typically require different kinds of interfaces to the data they store and the logic they implement: data loaders, user interfaces, integration gateways, and others. Despite their different purposes, these interfaces often need common interactions with the application to access and manipulate its data and invoke its business logic. The interactions may be complex, involving transactions across multiple resources and the coordination of several responses to an action. Encoding the logic of the interactions separately in each interface causes a lot of duplication. A Service Layer defines an application's boundary [Cockburn PloP] and its set of available operations from the perspective of interfacing client layers. It encapsulates the application's business logic, controlling transactions and coordinating responses in the implementation of its operations. PoEAA ServiceLayer
Microsoft: You are designing an enterprise application, and you need to make some of its functionality available across a network. This functionality needs to be accessible to various types of systems, so interoperability is a key aspect of the design. In addition to interoperability, you also may need to support different types of communications protocols and accommodate varying operational requirements. MPP ServiceInterface
Since there are so many different definitions for a service (see above), each discussion about what a service could look like seems to end in an endless loop. It is clear that we occasionally need 'a' service. In a recent project we defined a service class per use-case. A service class and its operations act as route signs to the consumers of the domain model. Mark den Hartog made the following comment:
Route signs point you in the right direction, they only take you as far as the "how to reach your end destination". A service should take you from point A to B without leaking the "how".
Although he does have a point, I still think that in terms of the domain model you need to know about the implementation details inside your service. Mark’s (being an integration specialist) comments drive towards MPP ServiceInterface and PoEAA ServiceLayer.
Another interesting metapor I have borrowed from Mark:
We find the Domain Model Service as an internal procedure within the city hall. The form is translated to specific domain objects and distributed to one or more persons handling the request. All persons have some knowledge of the procedures of the other persons, how much depends on the complexity of the tasks.
So, essentially the Domain Model Service is an integral part of the application and may therefore have knowledge of the internal structure of the domain, like business exception handling, object discovery etc. A Domain Model Service encapsulates behavior of the domain that does not fit in the domain objects themselves. Typical characteristics of a Domain Model Service is that it tends to be procedural and does not carry any state.
Also see Applying the Application Layer in Domain-Driven Design.