Los Techies : Blogs about software and anything tech!

Services in Domain-Driven Design


Services are first-class citizens of the domain model.  When concepts of the model would distort any Entity or Value Object, a Service is appropriate.  From Evans' DDD, a good Service has these characteristics:

  • The operation relates to a domain concept that is not a natural part of an Entity or Value Object
  • The interface is defined in terms of other elements in the domain model
  • The operation is stateless

Services are always exposed as an interface, not for "swappability", testability or the like, but to expose a set of cohesive operations in the form of a contract.  On a sidenote, it always bothered me when people say that an interface with one implementation is a design smell.  No, an interface is used to expose a contract.  Interfaces communicate design intent, far better than a class might.

But most examples I see of Services are something trivial, such as IEmailSender.  But Services exist in most layers of the DDD layered architecture:

  • Application
  • Domain
  • Infrastructure

An Infrastructure Service would be something like our IEmailSender, that communicates directly with external resources, such as the file system, registry, SMTP, database, etc.  Something like NHibernate would show up in the Infrastructure.

Domain services are the coordinators, allowing higher level functionality between many different smaller parts.  These would include things like OrderProcessor, ProductFinder, FundsTransferService, and so on.  Since Domain Services are first-class citizens of our domain model, their names and usages should be part of the Ubiquitous Language.  Meanings and responsibilities should make sense to the stakeholders or domain experts.

In many cases, the software we write is replacing or supplementing a human's job, such as Order Processor, so it's often we find inspiration in the existing business process for names and responsibilities.  Where an existing name doesn't fit, we dive into the domain to try and surface a hidden concept with the domain expert, which might have existed but didn't have a name.

Finally, we have Application Services.  In many cases, Application Services are the interface used by the outside world, where the outside world can't communicate via our Entity objects, but may have other representations of them.  Application Services could map outside messages to internal operations and processes, communicating with services in the Domain and Infrastructure layers to provide cohesive operations for outside clients.  Messaging patterns tend to rule Application Services, as the other service layers don't have a reference back out to the Application Services.  Business rules are not allowed in an Application Service, those belong in the Domain layer.

In top-down design, we typically start from the Application or Domain Service, defining the actual interface clients use, then use TDD to drive out the implementation.  As we're always starting from the client perspective with actual client scenarios, we get a high degree of confidence that what we're building will create success and add value.  When stories are vertical slices of functionality, this is fairly straightforward, at least mechanically so.

I used to make the mistake of dismissing Services as a necessary evil, confined to the Infrastructure layer.  Through more reading and conversation through our recent Austin DDD Book Club, I've started to realize the potential the Application and Domain services have in creating a well-designed model.

Kick It on DotNetKicks.com
Posted Aug 21 2008, 08:07 AM by bogardj

Comments

Dale Smith wrote re: Services in Domain-Driven Design
on 08-21-2008 12:18 PM

Hi Jimmy,

I'm way down the curve on DDD - I read Evans a long time ago, and I just read Nilsson's book, but there's still much I don't understand due to limited experience with modelling a rich problem domain using DDD.

One question I still have is: where is the right place to model cross-aggregate relationships?  Are services an appropriate place?  

Udi Dahan wrote re: Services in Domain-Driven Design
on 08-22-2008 7:13 AM

Jimmy,

I had a recent back-and-forth with Ayende on this topic on the back of the ALT.NET conference in Israel.

This is the best link I have for that:

groups.google.com/.../878a2311e4d35285

My guidance is not to have classes in the domain model call services at all, preferring to raise an event (usually on a separate static class in the domain, say, DomainEvents). Classes external to the domain can subscribe to these events and do what needs to be done - like email.

In many cases, the more general solution for this kind of logic is a saga.

Hope that makes sense.

Sean Chambers wrote re: Services in Domain-Driven Design
on 08-22-2008 7:20 AM

DDD Services are probably the most confused and discussed aspects of DDD. I see conversations popup on the mailing list frequently asking questions about services.

@Dale

I would say it depends on the context. If it makes sense to use a service to coordinate communication between aggregates because the required behavior doesn't really fit in one aggregate or the other then a service would be appropriate.

Another thing to note here is that Domain Services should only be working with instances of Entities/Value Objects in the domain, that is, you should already have the required objects from a Repository/Aggregate and provide them to the domain service. Having the Domain Service retrieve the objects from persistence storage is a smell, at least in my book. An application service however is different. I normally have application services communicate directly with repositories to complete their work if required.

Jimmy, Do you find the same thing with your experience or do you handle it differently?

I think the DDD community would be well served with more real world examples of Services in each context that would help communicate how people are actually using Services in their applications.

Dew Drop - August 22, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - August 22, 2008 | Alvin Ashcraft's Morning Dew
on 08-22-2008 8:30 AM

Pingback from  Dew Drop - August 22, 2008 | Alvin Ashcraft's Morning Dew

Implementing a Customer Search Service with DDD, BDD and the Entity Framework « Cav’s Weblog wrote Implementing a Customer Search Service with DDD, BDD and the Entity Framework « Cav’s Weblog
on 10-08-2008 6:13 PM

Pingback from  Implementing a Customer Search Service with DDD, BDD and the Entity Framework « Cav’s Weblog

Ian Cooper [MVP] wrote The Fat Controller
on 12-03-2008 7:26 AM

My latest project is built using the Castle Project stack ( Monorail , Windsor , and Active Record )

Community Blogs wrote The Fat Controller
on 12-03-2008 12:14 PM

My latest project is built using the Castle Project stack ( Monorail , Windsor , and Active Record )

Getters and Setters: a people problem « I Built His Cage wrote Getters and Setters: a people problem « I Built His Cage
on 12-10-2008 8:28 PM

Pingback from  Getters and Setters: a people problem « I Built His Cage

Artur Trosin's blog wrote Domain Driven Design: Learning
on 02-09-2009 8:48 AM

1. Introduction In the post I would like to help folks who want to improve their design skills and way

???????????? ?????????????????????????? ???? ???????????? ???????????????????? ?????????????? (DDD: Domain Driven Design) « butaji wrote ???????????? ?????????????????????????? ???? ???????????? ???????????????????? ?????????????? (DDD: Domain Driven Design) « butaji
on 06-06-2009 2:49 PM

Pingback from  ???????????? ?????????????????????????? ???? ???????????? ???????????????????? ?????????????? (DDD: Domain Driven Design) « butaji

Vitaly Baum wrote Учимся проектировать на основе предметной области (DDD: Domain Driven Design)
on 06-06-2009 2:57 PM

В данной статье я хотел бы рассказать об этих трёх буквах, постоянно находящихся

Roy wrote re: Services in Domain-Driven Design
on 12-16-2009 12:49 PM

If the Application Layer calls a Domain Service, then shouldn't the Domain Service be a Static Class INSTEAD OF an Interface? I feel if a Domain Service is only an Interface, then that leaves the Application Layer with the responsibility to implement the business rules. I need clarification on this. This is the only aspect of DDD that confuses the hell out of me.

Thanks

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:
Copyright Los Techies 2008, 2009. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems