views:

334

answers:

2

In my Spring MVC application I am using DTO in the presentation layer in order to encapsulate the domain model in the service layer. The DTO's are being used as the spring form backing objects.

hence my services look something like this:

userService.storeUser(NewUserRequestDTO req);

The service layer will translate DTO -> Domain object and do the rest of the work.

Now my problem is that when I want to retrieve a DTO from the service to perform say an Update or Display I can't seem to find a better way to do it then to have multiple methods for the lookup that return different DTO's like...

EditUserRequestDTO userService.loadUserForEdit(int id);

DisplayUserDTO userService.loadUserForDisplay(int id);

but something does not feel right about this approach. Perhaps the service should not return things like EditUserRequestDTO and the controller should be responsible of assembling a requestDTO from a dedicated form object and vice versa.

The reason do have separate DTO's is that DisplayUserDTO is strongly typed to be read only and also there are many properties of user that are entities from a lookup table in the db (like city and state) so the DisplayUserDTO would have the string description of the properties while the EditUserRequestDTO will have the id's that will back the select drop down lists in the forms.

What do you think?

thanks

+1  A: 

I like the stripped down display objects. It's more efficient than building the whole domain object just to display a few fields of it. I have used a similar pattern with one difference. Instead of using an edit version of a DTO, I just used the domain object in the view. It significantly reduced the work of copying data back and forth between objects. I haven't decided if I want to do that now, since I'm using the annotations for JPA and the Bean Validation Framework and mixing the annotations looks messy. But I'm not fond of using DTOs for the sole purpose of keeping domain objects out of the MVC layer. It seems like a lot of work for not much benefit. Also, it might be useful to read Fowler's take on anemic objects. It may not apply exactly, but it's worth thinking about.


1st Edit: reply to below comment.

Yes, I like to use the actual domain objects for all the pages that operate on a single object at a time: edit, view, create, etc.

You said you are taking an existing object and copying the fields you need into a DTO and then passing the DTO as part of the model to your templating engine for a view page (or vice-versa for a create). What does that buy you? The ref to the DTO doesn't weigh any less than the ref to the full domain object, and you have all the extra attribute copying to do. There's no rule that says your templating engine has to use every method on your object.

I would use a small partial domain object if it improves efficiency (no relationship graphs to build), especially for the results of a search. But if the object already exists don't worry about how big or complex it is when you are sticking it in the model to render a page. It doesn't move the object around in memory. It doesn't cause the templating engine stress. It just accesses the methods it needs and ignores the rest.


2nd edit: Good point. There are situations where you would want a limited set of properties available to the view (ie. different front-end and back-end developers). I should read more carefully before replying. If I were going to do what you want I would probably put separate methods on User (or whatever class) of the form forEdit() and forDisplay(). That way you could just get User from the service layer and tell User to give you the use limited copies of itself. I think maybe that's what I was reaching for with the anemic objects comment.

GMK
Thanks for the reply. If you use the domain object for an edit operation then do you also use the domain object for a new operation and everything else, why only for an edit? In my case I am stuck with an anemic domain object, can't do anything about that. The reason for the DTO's is that my domain objects are complex with many relationships and properties that I dont need for my views.
arrages
see my comments above...
GMK
Thank GMK, The reason I was thinking on doing this is not becuase it's lighter on the system. I think there is a legitimate reason for what I want to do. It's true I dont have to use anything I don't need from the domain object, but using the object to get what I need can be difficult at times, there is also a security concern as the view would have access to fields it should not have, and locking down the object is probably just as much trouble.
arrages
A: 

Great discussion for the topic: http://forum.springsource.org/showthread.php?t=64862&page=1

yazan jber