7

I am reading Evans's Domain Driven Design. The book says that there are entity and there are services. If I were to implement an operation, how to decide whether I should add it as a method on an entity or do it in a service class?

e.g. myEntity.DoStuff() or myService.DoStuffOn(myEntity)?

Does it depend on whether other entities are involved? If it involves other entities, implement as service operation? But entities can have associations and can traverse it from there too right?

Does it depend on stateless or not? But service can also access entities' variable, right? Like in do stuff myService.DoStuffOn, it can have code like

if(myEntity.IsX) doSomething();

Which means that it will depend on the state?

Or does it depend on complexity? How do you define complex operations?

4 Answers 4

2

Does it depend on whether other entities are involved? If it involves other entities, implement as service operation?

This is one good rule of thumb. Another: logic that describes a fundamental fact about the entity and is used in multiple use cases probably belongs into the entity. Logic that is use case specific probably doesn't. Both of these are variants of the Single Responsibility Principle.

But entities can have associations and can traverse it from there too right?

Yes, but entities should not be tightly coupled like that. Except perhaps in cases where one entity "contains" another and they are already tightly coupled conceptually.

Or does it depend on complexity? How do you define complex operations?

That's just a basic rule of code cleanliness: if a piece of code becomes too large and complex, break it up. If you have an operation as part of an entitry that containes more code than the rest of the entity together and you've already had to refactor it into sub-operations, you should think about moving it out of the entity entirely.

2

As far as I'm concerned, I always try to add an operation into an Entity before considering using a Service, because that's the natural place you'll look in if the operation is closely related enough to the Entity.

Just because a method involves several entities doesn't mean it can't be placed into one of them. Especially, invariants and business rules that span across several of an Aggregate's Entities are often implemented in the Aggregate Root.

I only use a Service if the operation doesn't seem to belong in any of the existing Entities. A good example of that is the TransferFunds() method. Should it be a method of the source account ? It would mean the source account can alter the balance of the destination account, which seems a bit weird. Same thing with the destination account.

So this is a perfect case for a FundsTransferService with the following method :

public void TransferFunds(Account source, Account destination, decimal amount)

It shouldn't happen all that often though.

Also, keep in mind that it's not just an Entities vs Services world. You've got plenty of other objects to put your operations in - Factories, Policies, Specifications, etc.

1

Just pick the most intuitive/simple one for the corresponding situation.

To illustrate this more clearly, let me pick more specific names than "myEntity" and "DoStuff"

   myService.process(myData) // fits perfectly.

   myStatefulThingy.reset() // fits perfectly.

In the first case, myData/myEntity is merely some data passed to a service. In the second one, it's a self contained operation.

I recommend that in the first case, myData/myEntity is not altered while in the second case myStatefulThingy/myEntity is the only thing which gets modified.

6
  • maybe for a seasoned programmer, it's intuitive, but for me it's often not. For example, without a more specific rule I don't know which one is more natural: myData.Transform(); or myTransformer.Transform(data);
    – Louis Rhys
    Commented Apr 3, 2012 at 8:38
  • There is no magical rule for this. It depends on the situation. If you give us a more precise practical case, we may advise you better. Else, it becomes abstract mumbo jumbo.
    – dagnelies
    Commented Apr 3, 2012 at 8:44
  • Indeed I am asking about a generic rule of thumb. I know that there is no magical rule that works 100%, but I want to know how to "intuit" as easily as you apparently do and acquire that intuition, maybe there is a good rule of thumb? I am not making any concrete decision right now
    – Louis Rhys
    Commented Apr 3, 2012 at 8:53
  • 2
    As a rule of thumb: if the goal is to modify the state of the object, put the method in it. If the goal is to transform an input into an output, use a service which leaves the input object intact and creates an output object.
    – dagnelies
    Commented Apr 3, 2012 at 8:57
  • I realize maybe it's hard to answer without any specific example, maybe you can propose some example, and I'll also think of some concrete situation to illustrate
    – Louis Rhys
    Commented Apr 3, 2012 at 8:58
1

Following this very good article by Martin Fowler you should tend to keep your Business Logic in your Entities and your Service Layer thin. I don't think it's a question of complexity. If other entities (not "owned" entities) are involved, I would recommend to use the Service Layer for delegating to Business Logic in other entities.

You should read this article! Martin Fowler refers to the book you're currently reading in regard to your issue.

1
  • As Martin's article (and the DDD book) says, business logic goes mostly into entities and services in the Domain Layer, not in the Application Layer (what you call "Service Layer").
    – Rogério
    Commented Apr 15, 2016 at 17:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.