Against the background of my enthusiastic study of DDD, I read an article by Martin Fowler dated November 25, 2003 from the Anemic Domain Model . Sometimes, for a better understanding of the material, I translate it into Russian. So I decided to share the translation.
Translation of the author and in some places very semantic.
Link to the original .
The article has quotes from the already published book, which was translated into Russian by professionals, in order to improve the understanding of my translation, I quoted from the book under the spoilers.
')
Pale Domain ModelThis is one of those anti-patterns that has surrounded us for a long time, and now it is even more active. I talked about this with Eric Evans and we both noted that he is becoming more and more popular. And I, as a supporter of the right Domain Model, believe that this is not good.
The first symptoms of the Pale Domain Model are that it looks normal, but only at first glance. Objects are named as nouns from the subject area, interconnected and have the structure of normal domain objects. Understanding comes when viewing their contents, it is hardly more than a set of getters and setters. Often these domain objects come with architectural rules not to place any domain logic in them. Instead, there is a set of services (service objects) that contain all the domain logic in themselves. These services are located architecturally above the domain model and use it as a data source.
The whole horror of this anti-pattern is that it goes against the basic idea of ​​Object Oriented Design, which consists in combining data and process (behavior). The pale model is something of a procedural design, something that fans like me and Eric have been fighting from the very first days of their work with Smalltalk.
Nowadays, Object-Oriented Purism is good, but I think we need more compelling arguments against this “pallor” in the model. The problem with the Pale Domain Model is that it carries the entire load of the Domain Model without bringing its advantages. And we pay for it with the absurdity of database mapping, which usually results in a whole layer of ORM. This makes sense only when powerful Object-Oriented techniques are used to organize complex logic. However, moving all the system behavior into services, you need to understand that everything will end
badly in Transaction Script , and you will certainly lose all the advantages that the Domain Model has. But as I said in the book
P of EAA, the Domain Model is not always the best choice.
It is also worth noting that the placement of behavior in Domain Objects should not contradict the consistent approach of using layers to separate the domain logic from the layer of persistence and presentation. The logic that should be in the domain object is the domain logic, for example: validation, calculations or whatever you call the “business rule”.
(There are cases, of course, when you pass a parameter to the domain object with a data source or pieces of presentation logic, but this is orthogonal to my idea of ​​“pallor”.)
One of the sources of misinterpretation is that many Object Oriented experts recommend placing a layer of procedural services
over a domain model in order to form a service layer. But this is not an argument not to place the behavior in the domain model, in fact, the service layer pushes to use it in conjunction with the domain model containing the behavior.
Erik Evans' excellent book "
Domain Driven Design " talks about these layers.
Application Layer [as he calls the Service Layer]: defines the tasks that it is supposed that the application will solve and directs their execution to the (rich) domain model. The tasks of this layer are significant for business (not business logic) or are simply interaction with the application layer of other systems. This layer should remain thin. It does not contain business logic or any knowledge, it only coordinates tasks and delegates work to sets of domain objects at a lower level. It does not carry a state that reflects the situation in business logic, but may be aware of the status of the task to inform the user and / or application as a whole.
From bookDefines the tasks that the task must solve, and distributes them between objects that express the essence of the subject area. Tasks performed by this level make sense for a specialist user or are necessary for interactive interaction with operational levels of other systems. This level does not need to "inflate" in size. It does not contain neither knowledge nor business rules (business rules), but only the coordination of tasks and the distribution of work between sets of domain objects at the next lower level. It does not reflect the state of the objects of the applied model, but it may contain a state that informs the user about the degree of completion of the task to inform the user.
Domain Layer (or Model Layer): Responsible for presenting the meaning of business processes, carries information about the business situation and business rules (business logic). Here, the state that reflects the situation in the application (in its business part) is monitored and used, even if the technical details of data storage (persistence) are allowed and delegated to the infrastructure.
This layer is the heart of the application.
From bookResponsible for introducing the concepts of the applied domain, working conditions, business regulations. This is where the current state of the applied model is monitored and used, even if the technical details of data manipulation are delegated to the infrastructure. This level is the main, algorithmic part of the program.
The point here is that the Service Layer is
thin , and all the logic is in the Domain Layer. He (Eric) repeats this in his
service pattern.Now it’s a common mistake to surrender too soon when putting behavior into the appropriate object, gradually slipping into procedural programming.
From bookAt this point, it is easy to make a common mistake: to abandon the attempt to place an operation in an object suitable for it, and thus come to procedural programming.
I don't know why this anti-pattern is so common. I suspect this from the fact that there are so many people who did not work with the
correct domain model, especially if they came from the world of data. Some technologies encourage this anti-pattern, such as J2EE's Entity Beans, this is one of the reasons why I prefer
POJO domain models.
In general, the more your logic in services, the more it seems that you left yourself without the advantages of the Domain Model. And if all your logic in services, then you stupidly rob yourself.
Thanks for attention.
I do not pretend to invite, because I do not need it. But if someone thinks that the material is worthy of an invite, just let us know in the comments, I will be pleased.