Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anemic Domain Model: Pros/Cons

I would like to know what the pros and cons are for using an Anemic Domain Model (see link below).

Fowler Article

like image 313
Steve Horn Avatar asked Nov 03 '08 12:11

Steve Horn


People also ask

Are Anemic domain Models bad?

Why is Anemic Domain Model harmful? One could say that the Anemic Domain Model is not going along with Object-Oriented Design. The separation of logic into other class is just not correct in OOD approach. But it is not the primary reason why Anemic Domain Model is harmful.

What are anemic domain models?

The Anemic domain model is a programming Anti-pattern where the domain objects contain little or no business logic like validations, calculations, rules, and so forth. The business logic is thus baked into the architecture of the program itself, making refactoring and maintenance more difficult and time-consuming.

What is an anemic object?

In object-oriented programming, and especially in Domain-Driven Design, objects are said to be anemic if they have state but lack behavior. Some kinds of objects, such as Data Transfer Objects (DTOs), are expected to simply be a collection of data.

What is an anemic class?

Anemic domain model is nothing more but entities represented by classes containing only data and connections to other entities. These classes lack of the business logic, which usually is placed in services, utils, helpers etc.


2 Answers

With "Anemic Domain Model" being anti-pattern, why are there so many systems that implement this?

I think there are several reasons

1. Complexity of the system

In a simple system (which is almost all the examples and sample code you find on internet) if I want to implement:

Adding product to Order

I put this function on the Order

public void Order.AddOrderLine(Product product) {     OrderLines.Add(new OrderLine(product)); } 

Nice and super object oriented.

Now let's say that I need to make sure that I need to validate that the product exists in inventory and throw exception if it doesn't.

I can't really put it on Order any longer, since I don't want my order to be dependent on Inventory, so now it needs to go on the service

public void OrderService.AddOrderLine(Order order, Product product) {     if (!InventoryService.Has(product)        throw new AddProductException      order.AddOrderLine(product); } 

I could also pass IInventoryService to Order.AddOrderLine, which is another option, but that still makes Order dependent on InventoryService.

There is still some functionality in Order.AddOrderLine, but usually it is limited to Order scope, while in my experience there is a lot more Business Logic out of Order scope.

When the system is more then just basic CRUD, you will end up with most of your logic in OrderService and very little in Order.

2. Developer's view of OOP

There are a lot of heated discussions on the internet about which logic should go on entities.

Something like

Order.Save

Should Order know how to save itself or not? Let's say we have repositories for that.

Now can Order add order lines? If I try to make sense of it using simple English, it doesn't really make sense either. User adds Product to Order, so should we do User.AddOrderLineToOrder()? That seems like overkill.

How about OrderService.AddOrderLine(). Now it kinda makes sense!

My understanding of OOP is that for encapsulation you put functions on classes where the function will need to access class's internal state. If I need to access Order.OrderLines collection, I put Order.AddOrderLine() on Order. This way class's internal state doesn't get exposed.

3. IoC Containers

Systems that use IoC containers are usually fully anemic.

It is because you can test your services/repositories which have interfaces, but can't test domain objects (easily), unless you put interfaces on all of them.

Since "IoC" is currently lauded as solution for all your programming problems, a lot of people blindly follow it and this way end up with Anemic Domain Models.

4. OOP is hard, procedural is easy

I have a bit of a "Curse of Knowledge" on this one, but I have discovered that for newer developers having DTOs and Services is a lot easier than Rich Domain.

Possibly it is because with Rich Domain it is more difficult to know on which classes to put the logic. When to create new classes? Which patterns to use? etc..

With stateless services you just slap it in the service with closest name.

like image 186
Eric P Avatar answered Oct 13 '22 04:10

Eric P


The pros:

  • You can claim it's a domain model and brag to your developer friends and put it on your resume.
  • It's easy to generate automagically from database tables.
  • It maps to Data Transfer Objects surprisingly well.

The cons:

  • Your domain logic exists somewhere else, probably in a class full of class(static) methods. Or your GUI code. Or in multiple places, all with conflicting logic.
  • It's an anti-pattern, so other developers will ask if you understand the concepts of object oriented design.
like image 41
Terry Wilcox Avatar answered Oct 13 '22 06:10

Terry Wilcox