Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question

4 Answers 4

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.

share|improve this answer

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.

share|improve this answer

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.

share|improve this answer
    
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 Apr 3 '12 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. –  arnaud Apr 3 '12 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 Apr 3 '12 at 8:53
1  
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. –  arnaud Apr 3 '12 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 Apr 3 '12 at 8:58

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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