I would like to know what the pros and cons are for using an Anemic Domain Model (see link below).
I would like to know what the pros and cons are for using an Anemic Domain Model (see link below).
The pros:
The cons:
"It's an anti-pattern, so other developers will ask if you understand the concepts of object oriented design."
"An anemic domain model is an anti-pattern. Anti-patterns don't have pros."
Whether the anemic domain model is an anti-pattern is a matter of opinion. Martin Fowler says it is, a number of developers who know OO inside out say it isn't. Stating opinion as fact is rarely helpful.
An, even if it was universally accepted to be an anti-pattern, the chances are it would still have some (though relatively little) upside.
It seems to me that Fowler's main objection is that ADMs are not OO, in the following sense. If one designs a system "from scratch" around passive data structures that are manipulated by other pieces of code, then this certainly smells more like procedural design than object-oriented design.
I suggest that there are at least two forces that can produce this kind of design:
Designers/programmers who still think procedurally being required to work in an object-oriented environment (or assuming that they can...) to produce a new system, and
Developers working to put a service-like "face" on a legacy system designed in a non-OO fashion (regardless of language).
If, for example, one were building a set of services to expose the functionality of an existing COBOL mainframe application, one might define services and interfaces in terms of a conceptual model that does not mirror the internal COBOL data structures. However, if the service maps the new model to the legacy data to use the existing-but-hidden implementation, then the new model might very well be "anemic" in the sense of Fowler's article -- e.g. a set of TransferObject-style definitions and relationships with no real behavior.
This kind of compromise may very well be common for the boundaries at which idealistically-pure OO systems must interact with an existing, non-OO environment.
"Developers working to put a service-like "face" on a legacy system designed in a non-OO fashion (regardless of language)."
If you think of many LOB applications, these legacy systems will often not use the same domain model as you do. The Anemic Domain Model solves this with the use of business logic in service classes. You could put all this interface code inside your model (in the traditional OO sense) - but you typically end up losing modularity.
After I first read Eric Evans book about Domain-driven design I did not really understand that it is not just a bunch of tactical patterns for designing good domain model classes.
After learning more about the topic and using the strategical patterns as well I finally started to understand that at first it is all about getting a deep understanding of the business problems you are trying to solve.
And only after that you can decide what parts of the system will fit for applying tactical patterns such as aggregates, entities, repositories, etc. along with so called rich domain models (as opposed to anemic ones). But in order to benefit from these patterns there has to be enough complexity concerning business logic for that part of the system.
So at when it comes to implementing the solution to the problem at hand it should first be determined if this specific problem is better approached with using a CRUD based approach or investing into a rich domain model along with the mentioned tactical patterns.
If CRUD makes more sense, e.g. if there is no complex business logic and most of the logic is concerned with transforming, transferring and persisting data implementing a domain model can be an unncessary overkill. This does not mean that there won't be a lot of work to do but simply the it's not the business rules which produce the most implementation effort. But in this case there is no such thing as an anemic domain model, simply because there is no domain model at all. What you will rather see are such things as DTOs (Data Transfer Objects) or DAOs (Data Access Objects) and service classes that will operate on the data. And the corresponding operations are to a high extent concerned with transforming data from one representation to another and moving data around with very little or almost no business logic at all.
If you determined that there is a lot of complex business logic which will also change over time than investing into a domain model is - from my experience - a good idea. The reason is that it is easier to represent the business perspective via code and make it easier to understand the corresponding operations that mirror the business domain and it's rules. This does not mean that there have to be domain model classes in every use case. For instance, if there is no state to be mutated and persisted there can also only be domain services which contain the domain logic are implemented more like pure functions.
But if there is also state to be mutated and persisted that also has purpose and meaning in the business domain the state and the behaviour that changes this state should be encapsulated. With that no one can get around the business rules that easy and by that lead to invalid states along with serious failures. So called anemic domain models are often sources of such problems. This is often the case if you see code where different components operate on the same "anemic" domain model class checking some part of it's state and changing some part of it's state without caring about or knowing the overall invariants of that business entity. It is not necessary to call this an anti-pattern but it is important to understand that you lose lots of benefits of rich domain models in a DDD based approach along with the mentioned problems. When using a domain model where behaviour and it's data are placed in the same class there can also be lot's of different "clients" calling operations of that class but they don't need to care that the business invariants of the business entity are adhered as the domain model class will always take care of that and can also inform the "client" about invalid operations or even throw exceptions as a safety net.
So bottom line, I think it is important to not confuse data-structure like classes (such as DTOs or DAOs) with anemic domain model classes. In a carefully and intentionally chosen CRUD based approach there is no advantage of trying to use a domain model because there is too less complex business logic.
By anemic domain model I would refer to code from which I can see that there is a lot of complex business logic and business rules that are spread across different components which should rather be close to the data these logic is changing.
There is also another lesson I learned along the way: if you try to use the same business language (also referred to as the Ubiquituous Language) in your code that the steakholders are using in their daily worklife you already win so many advantages concerning understanding of the business domain and improving the readability of your code that will help you so much no matter if you use a CRUD based or domain model based approach.
My team personally prefers the ADM. we have a set of business objects that represent specific parts of our domain. We use services to save these objects to the db. Our business objects do have methods, however these methods only manipulate it's internal state.
The benefit for us in using the ADM over RDM can be seen in how we persist the objects to db. Developers working on our legacy code systems can use our business objects(from the new system)and continue using their current data access layer to persist these objects to the db. Using the RDM would force developers of our legacy system to inject Repository objects into our business model...which would not be consistent with their current data access layer.