20

The anemic domain model is described as an anti-pattern in domain driven design by Martin Fowler. To have business logic on the domain models often domain services are used. But injecting domain services into domain models is considered harmful by Vaughn Vernon (see "Implementing Domain-Driven Design, Page 387).

In my opinion those opinions are contradictory, is this true? How can both points be considered?

Is it really rich domain model with domain services injected vs. anemic domain model and normal domain services?

3
  • 4
    I am by no means an expert on this, but I thought the type of logic that went into domain services and into domain entities was fundamentally different. The logic that goes into Entities is the logic needed to keep the object in a correct state. This involves validation and transformation logic. Domain services, on the other hand, are for higher level logic. So, for example, a domain service would model a business process that involves multiple different types of entities is complex ways.
    – MetaFight
    Commented Dec 17, 2015 at 15:46
  • 4
    @MetaFight: Even if a business process affects multiple entities in complex ways, you can achieve this without services given a good Aggregate Root domain model, that is, a domain model that has access to all the affected entities as properties or fields on itself. Commented Dec 17, 2015 at 18:06
  • That makes sense :)
    – MetaFight
    Commented Dec 17, 2015 at 18:08

2 Answers 2

16

An anemic model is simply a data container. It doesn't contain behavior. (This might actually be considered a good thing in the functional paradigm.) The opposite of an anemic model is not a model injected full of domain services. You're describing two extremes -- both are bad.

If you have an anemic model, you're not fully embracing what OOP offers. If you start injecting services into those models, you're likely injecting concerns that don't belong there. Either that or your model is more anemic than you think. Why else would you need the service other than it provides something that's required but missing? (Missing might mean anemic.)

Avoiding both "tells" leads to stronger design. Do you have something in a service that a model needs? Maybe it should be moved to the model. If not, maybe you should reconsider your concerns. A model's behavior should work inside the model. It should mainly (if not only) concern itself with members. But remember, there will still be things that work on or with the model. For example, models shouldn't be opening TCP connections or listening for UI events, even if they're somehow involved. That's someone else's responsibility and that someone never belongs inside the model.

2
  • 9
    A good distinction I like to remember is that your Domain Model implements business logic, and your Domain Services execute the business logic on the Domain Models. The difference is who is calling who. Services can call Domain Model methods. If Domain Models are calling Service methods, you've flipped the pattern on top of its head. Commented Dec 17, 2015 at 18:04
  • Actually it depends how You understand concept of a service. What a about cases when a domain object needs to vary its behaviour basing on something? Then it could be beneficial to inject a 'service' into a domain entity (eg tax calculator and so on).
    – Mic
    Commented Mar 20, 2020 at 13:11
7

It's not contradictory. Both proponents would like you to put your actual code in the domain object itself.

ie.

public class Order
{
    private string status = "not bought";
    public void Buy()
    {
        this.status = "bought";
    }
}

vs ADM

public class Order
{
    public string Status = "not bought";
}

public class BuyingService
{
    public Order Buy(Order order)
    {
         Order o = new Order();
         o.status = "bought";
         return o;
    }
}

vs injected services

public class Order
{
    public Order(IBuyingService bs)
    {
        _bs = bs;
    }
    private IbuyingService _bs;
    private string status = "not bought";
    public void Buy()
    {
        this.status = _bs.Buy();
    }
}

public class BuyingService : IBuyingService
{
    public string Buy()
    {
         return = "bought";
    }
}

Frankly though each approach has pluses and minuses. The one you choose is largely a matter of personal preference

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.