Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POCO's, DTO's, DLL's and Anaemic Domain Models

Tags:

I was looking at the differences between POCO and DTO (It appears that POCO's are dto's with behaviour (methods?))and came across this article by Martin Fowler on the anaemic domain model.

Through lack of understanding, I think I have created one of these anaemic domain models.

In one of my applications I have my business domain entities defined in a 'dto' dll. They have a lot of properties with getter's and setter's and not much else. My business logic code (populate, calculate) is in another 'bll' dll, and my data access code is in a 'dal' dll. 'Best practice' I thought.

So typically I create a dto like so:

dto.BusinessObject bo = new dto.BusinessObject(...) 

and pass it to the bll layer like so:

bll.BusinessObject.Populate(bo); 

which in turn, performs some logic and passes it to the dal layer like so:

dal.BusinessObject.Populate(bo); 

From my understanding, to make my dto's into POCO's I need to make the business logic and behaviour (methods) part of the object. So instead of the code above it is more like:

poco.BusinessObject bo = new poco.BusinessObject(...) bo.Populate(); 

ie. I am calling the method on the object rather than passing the object to the method.

My question is - how can I do this and still retain the 'best practice' layering of concerns (separate dll's etc...). Doesn't calling the method on the object mean that the method must be defined in the object?

Please help my confusion.

like image 884
dan Avatar asked May 22 '09 05:05

dan


1 Answers

Typically, you don't want to introduce persistence into your domain objects, since it is not part of that business model (an airplane does not construct itself, it flies passengers/cargo from one location to another). You should use the repository pattern, an ORM framework, or some other data access pattern to manage the persistent storage and retreival of an object's state.

Where the anemic domain model comes in to play is when you're doing things like this:

IAirplaneService service = ...; Airplane plane = ...; service.FlyAirplaneToAirport(plane, "IAD"); 

In this case, the management of the airplane's state (whether it's flying, where it's at, what's the departure time/airport, what's the arrival time/airport, what's the flight plan, etc) is delegated to something external to the plane... the AirplaneService instance.

A POCO way of implementing this would be to design your interface this way:

Airplane plane = ...; plane.FlyToAirport("IAD"); 

This is more discoverable, since developers know where to look to make an airplane fly (just tell the airplane to do it). It also allows you to ensure that state is only managed internally. You can then make things like current location read-only, and ensure that it's only changed in one place. With an anemic domain object, since state is set externally, discovering where state is changed becomes increasingly difficult as the scale of your domain increases.

like image 152
Michael Meadows Avatar answered Sep 19 '22 20:09

Michael Meadows