views:

152

answers:

5

I read an article.

In the source code, Entity objects are doing all the CRUD operations. This means Entity objects are calling the Repository directly from the methods.

The comments indicate:

Persistence is absolutely the resposibility of a domain object

Is this correct?

+1  A: 

"Persistence is an infrastructural aspect from which the domain layer should be decoupled": I'm quoting the article you mentioned.

Persistence is handled by the Repository implementation. Domain objects should be unaware of being belonging to such repositories.

Answering your question, I could say there is no right or wrong way of doing it, but the statement is controversial. Could be a best practice if your project is doing that in a consistent way and you're OK with the approach. In my opinion, domain objects should be unaware of persistence issues, so the the statement is false from a purist DDD view.

JuanZe
The author later said in the comments: Domain objects should also be responsible for persisting the data (CRUD) in addition to encapsulating the state and behavior of business domain entities and the business logic. This way, clients can call the domain objects directly to create and manipulate the domain state instead of relying on DAO's (which are infrastructure related classes in my opinion) to take care of the persistence. ... It's not always required for the Entities to call Repositories for CRUD functions.
AJ
I see the author point here, and is a valid way of doing it, if you are OK with that approach, but in my opinion that's not DDD
JuanZe
+1  A: 

Seems to me that the author is leaning towards an Active Record pattern. I am not sure that DDD strictly prohibits the use of Active Record, but I wouldn't use it.

See this article for a good briefing of the problems with Active Record and DDD together.

AJ
+1  A: 

His argument is that entity objects should be more than mere data carriers.

Instead of putting some entity logic in the DAO layer and some more logic into the business layer, he argues that all the logic for an entity should be in that entity.

This certainly has some merits. Example:

public class Parent {
    @Lazy
    private List<Children> children;
}

In your code, you fetch a parent from the DB. Some while later, you decide to do something with the children. In the DAO world, the DAO framework must somehow inject a hidden field somewhere which allows getChildren() to fetch the children of the parent from the DB.

If that field was part of Parent, it would be really obvious how this works.

The same goes for business logic: If you change something in your entity, you have to look up all places where it's being used as part of the business logic and make sure that the change doesn't break anything. This would be more simple if all business logic would be in the entity.

Unfortunately, this won't happen with OO languages. The main problem is that you'd have too much code in each entity and for some code, it wouldn't be clear at all in which entity it would belong. Imagine some business logic which reads data from an input entity and writes that to an output entity. In which entity does such code belong? The input or the output?

OO simply doesn't allow to chop such problems into digestible pieces.

Aaron Digulla
+1  A: 

If you read the comments, you'll see author explaining that the article was mostly to demonstrate DI techniques, not to promote good DDD design. There're several good issues with the sources code discussed in comments. So you better think twice before using it as reference.

To answer your question, it is usually not recommended to have entities work with repository interfaces, and especially with the persistence implementations. I would relate this to "goto" usage - this may be needed, but you won't usually expect to see it in the code.

I can also add, that it's much easier to use domain objects if you don't tie them to repositories. For example, you can build FitNesse (acceptance) tests with little effort, without messing with database or handling entities' calls to repositories. The easier to use domain objects alone, the better.

queen3
+1  A: 

Without reading the article I can say that I would never write my data access layer as part of the domain objects.

Domain Objects are one of the most sensitive parts of the application because they are being used in all the application layers. putting the persistence logic inside them will cause you a lot of trouble if you'll want to change the persistence layer some day.

furthermore, most of the code that is using those object should be indifferent to the fact that they are even persisted.

Moshe Levi