Reputation: 13466
I read this article today and am trying to clarify some things. Does this article mean that model objects should contain business logic? For example let us say that there is a Student object that we retrieve form the database via Hibernate. Does this article say that the Student object should contain business logic as well rather than having only getters and setters?
Upvotes: 1
Views: 210
Reputation: 9674
Disregard the date, what Martin Fowler states is as relevant today as it was eight years ago. Fowler does not state that you should mix persistence into the domain objects, quite the contrary:
"It's also worth emphasizing that putting behavior into the domain objects should not contradict the solid approach of using layering to separate domain logic from such things as persistence and presentation responsibilities."
You should read the article again, because the article describes this anti-pattern extermely well, but I shall try to summarize it for you in the context of what you are asking:
If you are to create a domain model, yes your domain objects should contain business logic as well as state, and changes to the state of your domain entities should be done through methods which convey business meaning. The anemic domain model is an anti-pattern because you incur the cost of an extra layer of classes but you are not reaping the benefits. Why bother with a domain layer which you have to map against the database when it convey exactly the same intent as you get from using an active record style approach (dataset, etc)? So the article does not say that you should have a "student-object", but it states that if you do, you should definitively add state to that class.
The point in the article about not having a set of objects to represent your model if you don't also model your domain can be a bit confusing due to the technologies available today. There are great tools out there which can effortlessly move data between a set of POCOs and the database (Nhibernate, EF, Simple Data, Massive, Dapper, etc) so in that retrospectiv I would say that you would probably end up with a set of "entities" in most solutions today, the real difference being whether this is just a database model or a real domain model.
I'll close up by showing you an example of the interaction between a domain entry point (command handler) and a domain model. The method shown below lives in a command handler which consumes a request to change something in the domain. Notice that the layer-ontop-of-your-domain-code simply gets the domain entity and calls one method on the domain? Thats an important point because the workflow we are modelling is fully encapsulated in the domain, not in the layer-ontop-of-your-domain-code or anywhere else:
public void Handle(AddEmailAddressForAlerts command)
{
var agent = _repository.GetAgent(command.AgentKey.AgentId);
agent.AddEmailAddressForAlerts(new EmailAddress(command.EmailAddress));
}
Upvotes: 6
Reputation: 308938
Notice the date - the citation is over eight years old.
Martin Fowler is obviously a very smart guy, and I like the article's point, but take it with a grain of salt. Encapsulating state and behavior together is a good thing in general, but it should be balanced against layering considerations. Persistence isn't the same thing as business logic. I'd still have a separate persistence tier; I wouldn't put persistence in a model object.
Dogma should be challenged in all its forms. Be aware of other people's ideas, but think for yourself.
Upvotes: 1