Separation of concerns - DAO, DTO, and BO

Josh Barker picture Josh Barker · Jan 19, 2010 · Viewed 7.1k times · Source

So I have a DAO, DTO, and BO. The following code is the result:

// Instantiate a new user repository.
UserRepository rep = new UserRepository();

// Retrieve user by ID (returns DTO) and convert to business object.
User user = rep.GetById(32).ToBusiness<User>();

// Perform business logic.
user.ResetPassword();
user.OtherBusinessLogic("test");
user.FirstName = "Bob";

// Convert business object back to a DTO to save to the database.
rep.Save(user.ToDataTransfer<Data.DTO.User>());

So I am trying to separate concerns, but I want to get rid of the "converts" in this code. The "converts" are actually located in the business logic layer (DTO layer knows nothing of the business logic layer) as an extension object. The DTO itself obviously only stores data and has no business logic what-so-ever. The UserRepository calls the DAO and at the end of GetById uses AutoMapper to map from the DAO to DTO. The "converts" (ToBusiness and ToDataTransfer) do exactly as they say.

A colleague of mine thought I may have to have a Business Repository, but thought it might be a bit clunky. Any thoughts?

Answer

Justin Niessner picture Justin Niessner · Jan 19, 2010

My only source of confusion here is why the calls to ToBusiness<User>() and ToDataTransfer<Data.DTO.User>() are necessary.

The responsibility of the Repository is to handle data management. It should hide the implementation details (as well as the conversions between Business Objects and Data Objects).

A UserRepository should return a User without any casting needed.

The UserRepository should also be able to persist a User without casting.

The code would be much cleaner if all the casting was handled in the Repository and your code read as:

UserRepository rep = new UserRepository();

User user = rep.GetById(32);

// Do Work Here

rep.Save(user);