An anemic domain model is one with no real logic in it, patched together by a bunch of getters and setters without domain specific logic and, importantly, clients have control over how to instantiate and modify a class. As a result, clients have to interpret the class purpose and use, typically through services, helpers, managers, where the domain logic exists in a separate class.
To avoid this, we can do the following:
- Define invariants. Invariants are what make your entities to be an entity. It is their essence and motive for them to exist. It is what makes an entity – Order being an order. Can an order exist without an order date?
- Think twice before using public parameterless constructors. It is very possible, like in the previous example, that in order to have a valid state your objects need some initialisation data. Prevent your clients from creating your objects in an inconsistent state.
- Get rid of public property setters for similar reasons. Don’t let the client decide on the internal representation of the entity; create methods that operate on these properties instead.
- Push your behaviour and domain rules from domain services to your domain model. If you find yourself creating a domain service, think again about your design and your entities. If you still feel that you need to create a domain service, try to use decorators instead. If nothing works, then create that domain service, but make sure you define it in terms of the language of the model and make it stateless. Bear in mind that domain services and domain behaviour are not the same concepts. Domain services act more as entities intermediaries while domain entities carry the domain behaviour.