I'm working on an application and have encountered two different approaches for organizing business logic. There's a general consensus that application rules should be handled in higher layers, so I don't think those are relevant here.
With Rich Models, state and behavior are bundled together within the entities, which seems to align well with traditional object-oriented design. However, as the system grows, I start to wonder: do these entities end up taking on too much responsibility? How do you handle behavior that needs to be shared across multiple entities? It feels like this could lead to complex inheritance hierarchies or even code duplication in order to keep things cohesive. I’m also concerned that this approach could introduce a lot of boilerplate as abstractions increase.
On the other hand, Anemic Models separate the entities’ state from the business logic, with the logic centralized in specific services. While this approach may seem more "procedural" since the logic isn’t inside the entities, I’ve seen definitions of object-oriented design that emphasize encapsulating both state and behavior together, but I’ve also seen arguments that this isn't always a hard rule. I’m left wondering if this separation could actually help with composing services and reusing logic across different parts of the system.
Additionally, it seems like the Anemic Model + Services approach could make testing easier because the responsibilities are more clearly separated. It also seems to favor composing services and handling batch operations, where the business logic doesn’t need to be scattered across multiple entities.
I’ve also heard the argument that if the service is well-defined and only handles business rules, the model isn’t really "anemic." In that case, the model would be the combination of the entity class and the service class, forming a complete unit of state and behavior. This leaves me even more unsure about the distinction between the two.
Notes
When I refer to Rich Models, I’m not talking about the Active Record pattern.
When I refer to Anemic Models and Services, I’m not suggesting a Big Ball of Mud, where the services end up accessing and doing everything. At least, I don't think I’m heading in that direction.
So, what are the best cases for using Rich Models versus Anemic Models with services? How can you manage the downsides of each approach as the system grows?
So far I haven't tested any of the approaches, although anemic models seem more correct.