Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
DDD: Services

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.

Download the eBook of the Series so far …

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 VO
  • 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 UL, they are the “things” that our Domain Experts and Users talk about.

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

In Conclusion

Services provide a way of expressing actions and operations within our domain. Where as Entities and Value Objects, the “things”, provide the building blocks, 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.

Previously:

1) Domain Driven Design: A Step by Step Guide
2) DDD: The Ubiquitous Language
3) DDD: Bounded Contexts
4) DDD: There Is No Database
5) DDD: Command Query Separation as an Architectural Concept
6) DDD: Entities and Value Objects
7) DDD: Where is the Code?
8) DDD: Download an eBook of the Series
9) DDD: Aggregates and Aggregate Roots

Reference:

InfoQ Free eBook : Domain Driven Design Quickly
Domain-Driven Design: Tackling Complexity in the Heart of Software (Eric Evans)

Services

del.icio.us Tags: DDD,Domain Driven Design,Practices and Principles


Posted 02-17-2009 9:38 PM by Jak Charlton

[Advertisement]

Comments

DotNetShoutout wrote DDD: Services - Casey Charlton - Insane World
on 02-17-2009 7:04 PM

Thank you for submitting this cool story - Trackback from DotNetShoutout

Reflective Perspective - Chris Alcock » The Morning Brew #389 wrote Reflective Perspective - Chris Alcock » The Morning Brew #389
on 02-18-2009 3:40 AM

Pingback from  Reflective Perspective - Chris Alcock  » The Morning Brew #389

Adam B wrote re: DDD: Services
on 02-18-2009 3:52 AM

For services that contain logic that would make the entity/vo bloaty or unwieldy, rather than those that contain logic that does not fit, should the entity/vo call the service from Entity.DoComplexThing() rather than the calling code? If so is it still a service in terms of DDD and the UL or just some supporting code?

Jak Charlton wrote re: DDD: Services
on 02-18-2009 4:20 AM

Entities don't call Services - your application calls services, those services may operate upon Entities

For example ... your app may call PricingService.GetPriceFor(customer, product)

For Entities that need access to logic external to them - we will touch on that soon with the Specification pattern

Michael Hart wrote re: DDD: Services
on 02-18-2009 8:07 AM

"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?

Jak Charlton wrote re: DDD: Services
on 02-18-2009 8:12 AM

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

on 02-18-2009 10:34 AM

CLR/Framework/WPF Brad Abrams continues the book excerpts with Framework Design Guidelines: Serialization Technology Scott Hansleman on Porting WPF Applications to the Microsoft Surface Prism/Silverlight Shawn reports that Prism now supports Silverlight

Casey Charlton - Insane World wrote DDD: What Kind of Applications Is It Suited To?
on 02-18-2009 2:20 PM

In many conversations, and in many comments here, you hear phrases like “well that’s not really suited

Community Blogs wrote DDD: What Kind of Applications Is It Suited To?
on 02-18-2009 2:39 PM

In many conversations, and in many comments here, you hear phrases like “well that’s not really suited

Claudio Lassala wrote re: DDD: Services
on 02-18-2009 4:29 PM

...and the plot continues...  :)

I'm really enjoying your DDD series. Keep up the great work!

Liam McLennan wrote re: DDD: Services
on 02-18-2009 4:42 PM

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.

Jak Charlton wrote re: DDD: Services
on 02-18-2009 4:55 PM

@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)

}

Sean Biefeld's Blog wrote Presenter Logic || Domain Service Logic || Repository Logic?
on 02-19-2009 12:11 AM

Obviously the answer to the titular question is yes. I have recently found myself questioning whether

Musings<Biefeld> » Blog Archive » Presenter Logic || Domain Service Logic || Repository Logic? wrote Musings&lt;Biefeld&gt; &raquo; Blog Archive &raquo; Presenter Logic || Domain Service Logic || Repository Logic?
on 02-19-2009 12:22 AM

Pingback from  Musings&lt;Biefeld&gt;  &raquo; Blog Archive   &raquo; Presenter Logic || Domain Service Logic || Repository Logic?

Casey Charlton - Insane World wrote DDD: The Repository Pattern
on 02-20-2009 3:30 AM

I seem to have taken a fairly long time to get here, and it has been mentioned in passing, but now we

Community Blogs wrote DDD: The Repository Pattern
on 02-20-2009 4:12 AM

I seem to have taken a fairly long time to get here, and it has been mentioned in passing, but now we

Casey Charlton - Insane World wrote DDD: Living In The Enterprise
on 02-21-2009 4:25 AM

No, not that Enterprise! The other Enterprise – the big amorphous one that organisation spent a fortune

Community Blogs wrote DDD: Living In The Enterprise
on 02-21-2009 4:48 AM

No, not that Enterprise! The other Enterprise – the big amorphous one that organisation spent a fortune

Insane World wrote DDD: The Repository Pattern
on 02-21-2009 10:42 AM

I seem to have taken a fairly long time to get here, and it has been mentioned in passing, but now we

Insane World wrote DDD: Living In The Enterprise
on 02-21-2009 10:42 AM

No, not that Enterprise! The other Enterprise – the big amorphous one that organisation spent a fortune

DDD Step By Step wrote DDD: What Kind of Applications Is It Suited To?
on 02-22-2009 3:36 PM

In many conversations, and in many comments here, you hear phrases like “well that’s not really suited

DDD Step By Step wrote DDD: The Repository Pattern
on 02-22-2009 3:36 PM

I seem to have taken a fairly long time to get here, and it has been mentioned in passing, but now we

DDD Step By Step wrote DDD: Living In The Enterprise
on 02-22-2009 3:37 PM

No, not that Enterprise! The other Enterprise – the big amorphous one that organisation spent a fortune

Insane World wrote DDD: Living In The Enterprise
on 02-26-2009 4:08 PM

No, not that Enterprise! The other Enterprise – the big amorphous one that organisation spent a fortune

Insane World wrote DDD: The Repository Pattern
on 02-26-2009 4:08 PM

I seem to have taken a fairly long time to get here, and it has been mentioned in passing, but now we

IHateSpaghetti {code} wrote Blog Carnival #14
on 03-01-2009 1:08 PM

Software architecture Evolutionary Design and Acyclic componentization by Patrick Smacchia Carnival of

Billy McCafferty wrote Drawing the Line Between MVC Controllers and DDD Application Services
on 09-16-2009 2:28 PM

Frequently, when we adapt new technologies or techniques, the new fix ends up introducing new "yucky"

Jason wrote re: DDD: Services
on 03-11-2010 2:23 PM

Is there any rule that says that domain services cannot use infrastructure to accomplish a task? In other words, can a domain service call a repository to load another aggregate (or aggregates) to do its work?

A good example would be a tax calculation. Say we have a set of tax rules that retreive with a TaxRulesRepository that we dont want to be loaded with our Product aggregate. Should we have it retreive it, or just pass those rules into the service method?

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)