91

I am reading Domain-Driven Design by Evans and I am at the part discussing the layered architecture. I just realized that application and domain layers are different and should be separate. In the project I am working on, they are kind of blended and I can't tell the difference until I read the book (and I can't say it's very clear to me now), really.

My questions, since both of them concerns the logic of the application and are supposed to be clean of technical and presentation aspects, what are the advantages of drawing a boundary these two?

Louis Rhys
  • 6,182

7 Answers7

55

I recently read DDD myself. When I got to this section I was pleasantly surprised to find out I discovered the same 4-layer architecture that Evans did. As @lonelybug pointed out, the domain layer should be completely isolated from the rest of the system. However, something has to translate UI-specific values (query strings, POST data, session, etc.) into domain objects. This is where the application layer comes into play. It's job is to translate back and forth between the UI, the data layer and the domain, effectively hiding the domain from the rest of the system.

I see a lot of ASP.NET MVC applications now where almost all the logic is in the controllers. This is a failed attempt to implement the classic 3-layer architecture. Controllers are difficult to unit test because they have so many UI-specific concerns. In fact, writing a controller so that it isn't directly concerned with "Http Context" values is a serious challenge in and of itself. Ideally, the controller should be just perform translation, coordinate work and spit back the response.

It can even make sense to do basic validation in the application layer. It's okay for the domain to assume the values going into it make sense (is this a valid ID for this customer and does this string represent a date/time). However, validation involving business logic (can I reserve a plane ticket in the past?) should be reserved for the domain layer.

Martin Fowler actually comments on how flat most domain layers are these days. Even though most people don't even know what an application layer is, he finds that a lot of people make rather dumb domain objects and complex application layers that coordinate the work of the different domain objects. I'm guilty of this myself. The important thing isn't to build a layer because some book told you to. The idea is to identify responsibilities and separate our your code based on those responsibilities. In my case, the "application layer" kind of evolved naturally as I increased unit testing.

Travis Parks
  • 2,573
40

The domain layer models the business of your application. This should be your clear interpretation of it's rules, it's component dynamics and contains it's state at any given moment.

The application layer is concerned with defining the jobs needed to be done to accomplish a certain application task. Mainly, it is responsible for mandate the necessary domain work and interacts with other (external or not) services.

For example, my financial software application has a user operation for changing the state of a model entity (entity as defined in DDD [89]):

  • "The Chief of operations can approve a financial proposal".

But, as an application process, besides all the model consequences of this operation, I have to send an internal communication to other users of the application. This kind of work is "orchestrated" in the application layer. I would not want my domain layer thinking about directing a messaging service. (and certainly this is not a presentation layer responsibility). Whatever way, one thing is for sure: I need a new layer as my domain layer is all about the core business and my presentation layer is all about interpreting user commands and presenting results.

Notes:

  • Business is one of those words that frequently lead to multiple interpretations of it's meaning but for sure you can find lots of examples and talk-about in DDD;
  • DDD stands for Domain-Driven Design book by Eric Evans and number inside square brackets for page number.
Hidden
  • 103
32

Taking from Martin Fowler's patterns of enterprise design, the most common layers are:

  • Presentation - these are views, presentation templates which generate the interaction interface for your application (I am using interaction in case your application is accessed by other systems through web services or RMI so may not be a user interface). This also includes controllers which decide how actions will be executed and how.

  • Domain - this is where your business rules and logic resides, your domain models are defined etc

  • Data Source - this is the data mapping layer (ORM) and data source (database, file system etc)

How do you draw the boundaries between the three layers:

15
  • Application Layer and Domain Layer both comes under the scope of implementation.
  • Application Layer is acts as API.
  • Domain Layer is acts as a implementation of API, it contains business logic so it is also call Business Logic Layer.

enter image description here

Premraj
  • 916
9

Domain Layer should be designed as an isolation layer, which means the business logic and rules should not be affected with any codes (in Application Layer, Presentation Layer and Infrastructure Layer) changes.

Application Layer is suppose to be designed to provide some functions about what a system (application) interface (think this like an API or RESTful) can do. For example, users can log in a system, and in this application action (login), application layer codes will be the client codes for Domain Layer (or Infrastructure Layer), in which retrieves User domain object and apply this object's methods to implement the 'login' function.

Application Layer should also be designed as an isolation layer, which means the application's behaviours should not be affected with any codes (in Presentation Layer, Domain Layer and Infrastructure Layer) changes.

5

The point of Domain Driven Modelling is to separate the essential domain model out and have it exist without any dependencies on other layers and other application concerns.

This allows you to focus on the domain itself without distractions (such as coordinating between the UI and the persistence services).

Oded
  • 53,734
5

The main reason for these boundaries is separation of concerns. The code that accesses the data store should only have to worry about accessing the data store. It should not be responsible for enforcing rules upon the data. Additionally the UI should be responsible for updating controls in the UI, getting values from user input and translating them to something that the domain layer can use, and nothing more. It should call operations provided by the domain layer to perform any needed actions (e.g. save this file). A web service that is called should be responsible for converting from the transmission medium to something the domain layer can use, and then call the domain layer (most tools do a lot of this work for you).

This separation, when implemented properly can afford you the capability to change parts of your code without affecting others. For example, maybe the sort order of a returned collection of objects needs to change. Since you know that the layer responsible for data manipulation (usually the business logic layer) handles this stuff, you can easily identify where the code needs to be changed. As well as not having to modify how it is retrieved from the data store, or any of the applications using the domain (the UI and web service from my example above).

The ultimate goal is to make your code as easy to maintain as possible.

As a side note, some things cannot be pigeon-holed into a specific layer of the domain (e.g. logging, validation, and authorization). These items are commonly referred to as cross-cutting concerns, and in some cases can be treated as a layer that stands by itself that all the other layers can see and use.

Personally I think the layered approach is outdated, and that the service approach is better. You still have the stark line drawn in the sand as to who does what, but it doesn't force you to be as hierarchical. For example, a purchase order service, a billing service, and a shipping service, from the application perspective all of these services represent your domain, and the deferment of responsibility I described above is still valid in this context, it has just been altered such that your domain exists in multiple places, further utilizing the separation of concerns concept.