2

I am trying to understand how to separate the domain model from the persistence mode so that the two can vary independently as described here and here

I understand the benefit of mapping the ORM directly to the domain model i.e. speed of development. This would be my normal approach.

Say I wanted to separate the domain model from the data model. I have two questions:

1) My research tells me that the main limitation of doing this is change tracking. How is this a problem? I would map the domain model back to the data model to persist the changes - at that point NHibernate (my ORM) would find the changes.

2) Are there any examples of open source systems or examples that show how to separate the domain model from the data model?

I have read plenty of questions on here (and Stackoverflow) similar to mine e.g. this one. However, none answer my specific questions in my opinion.

2 Answers 2

3

To answer #1 - when separating the domain model from the persistence model, change tracking is not a problem. The reason is that change tracking is more of a cross-cutting concern than a domain concern. The concern of a domain model is not to ensure that changes to itself are tracked.

The changes we want to track are typically the ones that we also persist. IOW, if, in the course of some processing, we change a property value and then change it back, there is no change to persist, which means there's also no change to track. So I'd lean toward change tracking as a behavior of the persistence, not the domain.

Edited: Here's a note from Patters, Principles, and Practices of Domain-Driven Design:

Don't put dirty flags on domain objects
It might be tempting to put a flag on a domain object to signify that it has changed. The problem with this is that you are clouding the domain model with persistence concerns. Leave all change tracking to the unit of work and the repository.

For #2 - I don't have an open source example. But to start with, the separation between domain models and persistence models means ensuring that the persistence is abstracted, perhaps using the repository pattern.

If your domain models depend on a 'persistence ignorant' repository abstraction, like

public interface IRepository<T> where T : class
{
    void Add(T item);
    void Update(T item);
    void Delete(T item);
    void Get(RecordId id);
}

Then the implementation of that repository can map that T to and from whatever persistence-specific model is needed, and the domain will never know that the persistence model even exists.

In order for this to happen, the domain needs to define its own repository interface rather than injecting one defined in some persistence library. That leaves the domain persistence agnostic and easier to test, and only the implementation(s) of that repository know about the details of the persistence.

8
  • Sorry, but change tracking is cited as a problem everywhere e.g. here: enterprisecraftsmanship.com/2016/04/05/…, here: stackoverflow.com/questions/20944865/… etc.
    – w0051977
    Commented Dec 26, 2017 at 16:36
  • I added a reference to my answer which points to where the change tracking can happen. Here's another answer that elaborates on it. I agree, seeing a complete end-to-end example would be great. It's like Uncle Bob's "Clean Architecture." It looks totally awesome and makes sense, but I'd love to see an "Uncle Bob Certified" example. There's lots of ways to learn, and I like to learn by following a good example. Commented Dec 26, 2017 at 17:02
  • @w0051977: The first article you cite only says that you cannot benefit from change tracking [if you create your own persistence model], which is true, and should come as no surprise. That's a bit different than saying "change tracking is a problem." It took me quite awhile to figure out what you were talking about. The second article says the same thing. Commented Dec 26, 2017 at 17:07
  • +1 for "I'd lean toward change tracking as a behavior of the persistence, not the domain". I agree with this.
    – w0051977
    Commented Dec 26, 2017 at 18:01
  • I cannot see why there is an issue with change tracking i.e. it is still done in the data model even if there is a domain model i.e. the domain model is mapped back to the data model.
    – w0051977
    Commented Dec 26, 2017 at 18:02
0

Agreed, domain model and persistent store should be different concerns. Or one more step further, there should be NO persistent concern in OO at all. By saying that, I mean we should not model any object in OO for data store. Repository pattern fits very well, any object coming from the repository should be domain object. The data model is table/view structure in case of RDBMS and schema (or just json structure) of NOSQL.

In RDBMS, ORM does a quite good job on filling the gap between domain model and persistent. The only thing we need to take care is the map file or annotations (attributes in c#). Also, modern ORMs (such as hibernate) resolve change tracking very well, we do not need do anything in object level.

Personally, I would suggest:

  • Data model should only sit in data store and not leak to object model;
  • Data model should follow domain model;

For your second question, here is a java sample form Vaughn Vernon. The examples in Jimmy Nilsson's Applying Domain-Driven Design and Patterns: With Examples in C# and .NET are good for C# readers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.