DDD Step By Step
A Practical Guide to Domain Driven Design

Blogged Services

Blogged Services This page is locked to prevent further edits

Filed under: , ,

There can be no word more common in development, and no word used for such a multitude of different things as “service”

It was therefore unfortunate that Eric Evans introduced yet another concept of Service in DDD, one which has since been referred to by some as a Domain Service. However, people often use the term Service in isolation, as Eric did in his book – so if it is in relation to the Domain, it is probably what I prefer to call a Domain Service – otherwise it is likely to be one of those “other” services.

So … Domain Services Are … What?

Well, if Entities and Value Objects are the “things” in our Domain, the Services are a way of dealing with actions, operations and activities.

Shouldn’t Logic Be on the Entities Directly?

Yes, it really should. We should be modelling our Entities with the logic that relates to them and their children. But sometimes that logic either doesn’t fit on the Entity, or it would make the Entity bloated and unwieldy.

That is when Services come into the picture. They help us split logic that deals with multiple Entities, or that deals with complex operations or external responsibilities, into a separate structure more suited to the task.

So What Are the Characteristics of a Good Domain Service?

Oddly, they are much the same as the properties of any other good services… but to reiterate Eric Evans directly, they are:

 

  • The operation should be something that relates to a concept that does not naturally fit on an Entity or Value Object
  • The interface is defined in terms of the elements of the Domain Model
  • The operation is stateless

 

The first two of those are pretty obvious and easy to apply, the last is in general a good definition of a Service, and although some would argue there is no such thing as stateless, don’t express state explicitly, and presume instance of your Services should not affect each other.

Some Examples of Services

So far we have been using an ecommerce system as a basis for the examples, so I’ll continue here.

When a customer adds items to their shopping basket, they will expect to see the items totalled, and things like shipping costs calculated.

These things might conceivably sit on the Shopping Basket Entity – but a bit of deeper thought shows that this is probably not a perfect fit. For a simple system the basket might be able to contain all the logic required, but expanding our system and moving it to a DDD focus would probably extrapolate Services to deal with these issues – PricingService and ShippingCostingService could well be two of the players in this game.

After all, apart from needing to deal with the items in the Shopping Basket, these operations may well require communication with other services, calculation and pricing engines, external suppliers … in other words, they have a lot of responsibilities that we do not want to bring into our Entity.

Now instead of our ShoppingBasket having .GetTotalPrice and .GetShippingCost methods, we can use a Domain Service to get this information, and keep our Entity focused on the real tasks, managing the items in the ShoppingBasket

Services in the Ubiquitous Language

Entities and Value Objects live comfortably in the Ubiquitous Language, they are the “things” that our Domain Experts and Users talk about.

Services also live in the Ubiquitous Language, they are the actions that our  Domain Experts and Users talk about… where you see a noun in the conversation, it is likely to be an Entity or Value Object. When you see a verb, it may well be a Domain Service

In Conclusion

Domain Services provide a way of expressing actions and operations within our Domain. Where as Entities and Value Objects, the “things”, provide the building blocks, Domain Services provide the plumbing between them and allow us to express more abstract concepts.

Just beware of creating an anaemic domain model, Services are there to support Entities and VOs, not to strip their logic from them.

 

Recent Comments

By: Jak Charlton Posted on Mon, Feb 23 2009 3:21 AM

Michael Hart said:  

"Entities don't call Services"

I'm gonna sound like a broken record, but I don't think I agree with you on this :-)

What about Product.CalculatePrice(IPricingStrategy)? This would be a double dispatch scenario where the Product Entity would call the IPricingStrategy Service as part of its price calculation - I believe Jimmy Bogard has a post on this somewhere. Or do you not allow this type of pattern in your domain?

By: Jak Charlton Posted on Mon, Feb 23 2009 3:21 AM

Casey Charlton said:  

Double dispatch will be covered -as mentioned - when I cover Specifications

By: Jak Charlton Posted on Mon, Feb 23 2009 3:21 AM

Liam McLennan said:  

I think there are plenty of scenarios where it makes sense for an entity to call a service. I call these domain services and I call the other services, that you are talking about, application services.

By: Jak Charlton Posted on Mon, Feb 23 2009 3:21 AM

Casey Charlton said:  

@Liam

I am talking about domain services - application services aren't something I'm too interested in right now in this series.

Sure an app service may be making this call  PricingService.GetPriceFor(customer, product)

And as metnioned when we get to Specification we will be covering double dispatch .. which could make the former call into

product.GetPriceFor(customer, pricingService)

And within a limited scenario that is fine, but that can be quick to bloat

So, as with everything, balance is required ... but under no circumstances would I have:

product.GetPrice(customer) {

return PricingService.GetPrice(customer, product)

}

By: Alvaro Posted on Thu, Oct 8 2009 7:17 PM

Probably better names for "Domain Service" might be "Process Subcontractor" or "Process Supplier": a kind of outsourcing when the actions, operations or activities are beyond the primary competencies of the Entity or Value Object.

Thanks for the e-book!