Domain entities, the counter to transfer objects, embrace the idea that objects can be smarter than a post-it. Through domain-driven design, these objects understand that they have properties, and can ease the burden on the rest of an application by performing some of the behavior itself. This also reduces feature envy (see more on code smell), where service classes need to have an intimate knowledge of an object and its properties.
A simple example would be getting a comma-separated list of the names of a person’s children. A service class could loop through the children of a person, or ask the person and the person can do it. What if the children are in an array on the person, not a list? Or in a map? It’s easier to manage just the Person, than all instances where the children of a person are referenced.
Another interesting example is the construction of entities from JSON or XML. The parent object can create itself, then usher off the JSON or XML to the children to construct themselves. There are more efferent couplings, but tighter cohesion for the entities.
But where do you draw the line? I’ve seen objects that contain a static connection to a database. Transaction management is now contained in the Person object. I think this goes a little far. Sadly, I don’t know if there is a hard and fast rule for defining whether the functionality should go into the domain entity or remain in the service.
But here are some questions to ask yourself:
Is this behavior specific to this environment?
A “yes” for this question may be an immediate red flag. Database implementation is an example of this (hence why interfaces are defined for DAOs).
Does the behavior intersect with other entities?
Cross-cutting logic can be performed inside one of the entities where appropriate, but may have to be externalized based upon the breadth of the behavior.
How many getters am I using?
If you have to use a number of the properties of an object, it may be better for the object to do it.
If you have other considerations, please leave them in a comment!