20

I'm trying to figure out the best way to build an easily maintainable and testable architecture. Having gone through several projects, I've seen some pretty bad architectures and I want to avoid making future mistakes on my own projects.

Let's say I'm building a fairly complex three layer application and I want to use DDD. My question is, where should I place my business logic? Some people say it should be placed in services (service layer) and that does make sense. Having a number of services which adhere to Single Responsibility Principle makes sense.

However, some people said that this is an anti pattern and that business logic shouldn't be implemented in the service layer. Why is this?

Let's say we have IAuthenticationService which has a method with bool UsernameAvailable(string username) signature. The method would implement all required logic to check whether the username is available or not.

What is the problem here according to the "this is an antipattern" crowd?

DarkAjax
  • 15,955
  • 11
  • 53
  • 65
Vex
  • 1,179
  • 3
  • 15
  • 24

3 Answers3

25

If you put all your business logic in an (implicitly stateless) service layer you're writing procedural code. By decoupling behavior from data, you're giving up on writing object-oriented code.

That's not always bad: it's simple, and if you have simple business logic there's no reason to invest in a full-fledged object-oriented domain model.

The more complex the business logic (and the larger the domain), the faster procedural code turns into spaghetti code: procedures start calling each other with different pre- and post-conditions (in incompatible order) and they begin to require ever-growing state objects.

Martin Fowler's article on Anemic Domain Models is probably the best starting point for understanding why (and under what conditions) people object to putting business logic in a service layer.

Jeff Sternal
  • 47,787
  • 8
  • 93
  • 120
10

A service layer in itself is not an anti-pattern, it is a very reasonable place to put certain elements of your business logic. However, you do need to apply discretion to the design of the service layer, ensuring that you aren't stealing business logic from your domain model and the objects that comprise it.

By doing that you can end up with a true anti-pattern, an anaemic domain model. This is discussed in-depth by Martin Fowler here.

Your example of an IAuthenticationService isn't perhaps the best for discussing the problem - much of the logic around authentication can be seen as living in a service and not really associated with domain objects. A better example might be if you had some sort of IUserValidationService to validate a user, or even worse a service that does something like process orders - the validation service is stripping logic out of the user object and the order processing service is taking logic away from your order objects, and possibly also from objects representing customers, delivery notices etc...

David Hall
  • 32,624
  • 10
  • 90
  • 127
  • 1
    I've just found an MSDN article which says: "A service layer sits on top of an application's domain model and provides a set of operations that can be performed against it. This gives you a place to centralize logic that belongs in your application but might not necessarily belong inside the domain model—logic that would have otherwise likely leaked into the controller's methods." ...... I guess this is what you guys wrote, in a different wording. Still, how would you determine what belongs inside the domain model and what does not? – Vex Jul 31 '11 at 23:37
  • 3
    @Vex: people mean a lot of different things by 'service layer', but you can't go wrong if you try to put all your **business logic** into your domain model. (As opposed to **application logic** - see [this answer](http://stackoverflow.com/questions/2475136/how-useful-is-a-pure-mvc-implementation/2479207#2479207) for more about that distinction.) – Jeff Sternal Aug 01 '11 at 12:57
5

You have to have 4 layers with DDD: Presentation, Application, Domain, and Infrastructure.

The Presentation layer presents information to the user, interprets user commands.

All dependent on use-cases logic (application entities, application workflow components, e.g. DTOs, Application services) goes to the Application layer (Application logic). This layer doesn’t contain any business logic, does not hold the state of business objects, can keep the state of an application task’s progress.

All invariant to use-cases logic (business entities, business workflow components, e.g. Domain model, Domain services) goes to the Domain layer (Domain logic). This layer is responsible for concepts of the business domain and business rules.

The Infrastructure layer may have IoC, Cache, Repositories, ORM, Cryptography, Logging, Search engine, etc.

V. S.
  • 1,086
  • 14
  • 14