DTO or Domain Model Object in the View Layer?

ModelDtoData Transfer-Objects

Model Problem Overview


I know this is probably an age-old question, but what is the better practice? Using a domain model object throughout all layers of your application, and even binding values directly to them on the JSP (I'm using JSF). Or convert a domain model object into a DTO in the DAO or Service layer and send a lightweight DTO to the presentation layer.

I have been told it makes no sense to use DTOs because changes to the database will result in changes to all your DTOs whereas using Model Objects everywhere will just require changes to the affected model object. However, the ease of use and the lightweight nature of DTOs seems to outweigh that.

I should note that my app uses Hibernate Model Objects AND uses its own custom-created model objects (meaning not bound to any DB session, always detached). Is either of the above scenarios more beneficial to a strict Model Object pattern? Using Hibernate has been a huge PITA with regards to things like Lazy Initialization Exceptions.

I am editing this question in hopes of furthering discussion (not sure if I'm doing this right):

The problem I have with model objects is that they are not flexible at all. A comment below says that the application should be designed so that model objects can be used throughout all layers. Why? If a user wants a piece of ridiculous functionality, am I supposed to tell them, 'well that won't work with model objects'?

Plain and simple, there are just times when model objects won't work. You may have:

public class Teacher {
    List<Student> students;
    [tons of other Teacher-related fields]
}
public class Student {
    double gpa;
   [tons of other Student-related fields]
}

but maybe you don't need all that information. You just need the teacher's last name, the number of student's they teach this year, and average GPA for all students combined. What would you do in that case? Retrieve the full teacher information and student relationships and then your code gets a count on the List of Students, then computes a total average of all gpas inside? That seems like waaaay more effort than simply creating a DTO with 'String lastName', 'int numStudents', and 'double combinedGpa;

It may sound like my mind has been made up on these, but I have yet to work in an application where model objects can be completely used cleanly in every instance. Regular real-world applications with out-of-the-ordinary user demands just do not work that way.

Model Solutions


Solution 1 - Model

It really depends on the complexity of your application. Mixing domain objects into the view layer has two possible implications:

  1. You'll be tempted to modify your domain object to accommodate things you need in the view layer
  2. Your View layer will contain extra complexity caused by a mismatch between what your domain objects offer and what your view really needs. You might not be able to get around this complexity but it probably doesn't belong in the View layer.

If your domain objects are simple and your views are few, skipping the DTOs might be the simplest thing.

On the other hand, if your domain model is likely to evolve and become complex and if your views are likely to be numerous and varied, having view specific objects might be a good idea. In the MVC world, using ViewModels is common and makes a lot of sense to me.

Solution 2 - Model

Another vote for domain objects. As far as Domain Driven Design is concerned the domain model is the king and should be used where possible. The application should be designed in a way where most layers (bar Infrastructure layer) can use domain objects.

I think of DTOs as useful only where the objects need to be serialised. If there is no transfer over the wire or into an incompatible architecture I would not use them. DTO pattern is useful for keeping serialisation out of the domain object. Considering that UI/Domain interaction does not need serialisation, keep it simple and use the actual objects.

Solution 3 - Model

I think having DTO is not generally an anti pattern. There are a lot of people and systems using them and the benefit you get is the decoupled view layer that can be designed and modularized independently from the domain model. Although I agree that you should use domain objects where possible there are scenarios where you can get problems when you tie the view layer directly to the domain model.

I have made good experiences with a view model that only wraps around the domain objects and delegates most of the operations to them.This decouples view and domain layer, allows for flexible composition of domain objects and still is not much work to implement since IDEs support delegation pattern.

Solution 4 - Model

Scenarios when Domain Object are problematic to be sent :

  1. you may need aggregated information or other types of 'calculated fields' sent to the UI layer ( in example Flex / GWT ) and don't want to mess the Domain Object
  2. you may encounter a need for serializing cyclic object graph ( in your example, if Student had List relation ) , some protocols have problems with that
  3. Hibernate LazyInitializationException when dealing with the framework serializers ( blazeDS for flex / GWT serializer)

I'm not sure it's a clear cut answer in those cirumcstances

Solution 5 - Model

In my opinion, there's no problem at all with using domain model objects in every layer. You said that you don't need all of the information. When you're in your JSPs, use only the data that you need. No one is forcing you to fetch every property. You also said that you need to make calculations related to the object's properties in order to get GPA, # of students, etc. You have 3 options: create synthetic properties in your domain model object that return the right data for you, wrapped up nice and neat; do the calculations in either the controller or service layer, and expose them through the appropriate getters; or handle it all inside your JSP. You need to retrieve/compile/wrangle the data ANYWAY, so why add more complexity with a DTO.

Additionally, with each DTO, you're creating a.) an extra class you now have to maintain, and b.) at LEAST 1 extra method somewhere in some class that constructs and populates the DTO (DAO, factory method, etc.). More maintenance = unhappy developer 6 months later.

So, there are my arguments against DTOs. I do use them, but only in certain scenarios, like when I really need to optimize for speed and/or memory usage, and the cost of hydrating a full domain model object is way too much. Web services are a good example of when I prefer to use DTOs.

Solution 6 - Model

The behavior of a class, or its internal methods should not be exposed to layers not concerned with their behaviour. Transfer data, not behaviour. Use domain objects within the domain. The web is not a controlled domain, and UI developers need not be concerned with domain behaviour, just data.

The domain has to be encapsulated, and protected from modification by someone not concerned with the health of the domain.

Leaking behaviour is not the best habit.

If it is a small project, built it with correct principes as well. That way we always keep in mind why we do what we do, and not just how.

Solution 7 - Model

One of the reasons to use DTOs is when you need to display information to different types of users. E.g. you have an "account" domain model, and it has some property, e.g. "created_at". Depending on your business logic, you could show account to admins and to users, but users are not really allowed to know about creation date of an account (for some company secret reasons). Serving domain model to both admin and users could be very dangerous, especially if you are using JSON API, but if you split representation into 2 different DTOs - for admins and users, then it will be much safer. I have to say that it will require much more time to deal with and maintain this, but if your app requires this type of security and strictness, then you have no other choice.

Solution 8 - Model

I think what we should consider here in the first place is the cost of introducing new layer. Take DTO for instance - doing that we need a mapping. As someone said, translation is evil and should be avoided whenever possible.

On the other hand I think there are very few things that you generally should not do. Those who say all DTOs are evil are wrong - it always depends on the use case! Are they really justified?

And finally, I personally believe the domain objects should be let go to the view itself. Imagine what the wicket integration is then like. But take Spring MVC for instance - domain would stay then in the application layer probably...

Solution 9 - Model

DTO is widely considered an anti-pattern nowadays, and the advice is usually "avoid them at all costs".

One of the main advantages of an ORM framework like Hibernate, is that you can use domain objects at all levels, and don't really need DTOs. The caveat, of course, is that you have to dedicate sometime to THINK on those relationships: when to use lazy fetching, when to use eager, etc.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsmaView Question on Stackoverflow
Solution 1 - ModelsrmarkView Answer on Stackoverflow
Solution 2 - ModelIgor ZevakaView Answer on Stackoverflow
Solution 3 - ModelbennidiView Answer on Stackoverflow
Solution 4 - ModelAl1998View Answer on Stackoverflow
Solution 5 - ModelAquarelleView Answer on Stackoverflow
Solution 6 - ModelIlan YView Answer on Stackoverflow
Solution 7 - ModelKirill G.View Answer on Stackoverflow
Solution 8 - ModelkboomView Answer on Stackoverflow
Solution 9 - ModeldariopyView Answer on Stackoverflow