Domain entities vs presentation model objects

Domain entities vs presentation model objects

This is the first half of a two-part article. Read the second half here: Domain entities vs presentation model objects, part 2: mapping.

When putting domain driven design (DDD) principles to practice in a real application, it’s important to recognize the difference between your domain model and presentation model.

Here’s a simple real-life example from a little MVC application that displays a to-do list of tasks. The task domain entity is very simple, with an identifer, a name and an optional due date:

// task domain entitypublic class Task{    public int Id;    public string Name;    public DateTime? DueDate;    // ...etc}

Pretty much everything we want to know about this Task can be derived from its properties via Specifications. For example, an OverDueTaskSpecification will tell us whether or not the task is overdue by checking if the due date has already passed, and an UnscheduledTaskSpecification will tell us if the task is scheduled by checking if the due date is null.

However, when rendering the task to the user, the application’s view must remain dumb — a passive view — and cannot work this sort of stuff out for itself. It is not enough to simply pass a collection of domain entities to the view; all relevant details must be explicitly provided so the view has all the information it requires without having to do any work itself.

Together, all these UI-specific details form a presentation model object, which is effectively identical to a DTO in that it has only carries data and no methods or behaviour of its own (some people call them PTOs). Here’s what my application’s presentation model object for a task looks like:

// task presentation model objectpublic class TaskView{    public int Id;    public string Name;    public string DueDate;    public bool IsUnscheduled;    public bool IsOverDue;    public long SortIndex;}

The ID and name fields are exactly the same, but DueDate is now a string which will either hold a friendly-formatted date or ‘Anytime’ if the task is not scheduled. Unscheduled and overdue are now explicit flags so the view can immediately identify tasks that need special display like highlighting.

Most of the front-end user interaction in this application is implemented via JavaScript, so we need an index for sorting and appending tasks in the correct order. It needs to be simple to parse and fast to compare, so I chose a long integer which is resolved from the due date.

Note this is a very simple example with only one domain entity class which we just added some new properties to. Most real scenarios will require some degree of flattening aggregate object graphs into a single class, and hiding of fields which are not relevant.

In the big scheme of things, presentation model objects are defined in the application layer (see the Onion Architecture), where they are validated and mapped between domain entities. All public interfaces to the application layer are expressed in terms of presentation model objects, so domain entities do not leak into the UI layer.

In an ASP.NET MVC application for example, presentation model objects would be used as the Models for all views and action results.

Update: a friend asked me total why I don’t format DueDate in the view, as proper MVC separation of concerns would dictate. The reason is that as well as rendering them directly in the view when a page is requested, this application also sends presentation model objects to the client via AJAX. I decided that having one single place (instead of two) where tasks’ DueDates are formatted would make maintenance easier in the long run.