DTO or Domain Model Object in the View Layer?

a 夏天 提交于 2019-11-28 13:54:59

问题


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.


回答1:


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.




回答2:


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.




回答3:


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.




回答4:


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




回答5:


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.




回答6:


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.




回答7:


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...




回答8:


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.



来源:https://stackoverflow.com/questions/2680071/dto-or-domain-model-object-in-the-view-layer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!