aspose file tools*
The moose likes Struts and the fly likes A buildDTO() in Action or in ActionForm ??? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Frameworks » Struts
Bookmark "A buildDTO() in Action or in ActionForm ???" Watch "A buildDTO() in Action or in ActionForm ???" New topic
Author

A buildDTO() in Action or in ActionForm ???

Leandro Melo
Ranch Hand

Joined: Mar 27, 2004
Posts: 401
Hi,
in another post i tried to discuss this problem, but now i a little more mature and will try do be more specific.

I guess the best way (if i'm not correct, please let me know) to mount a DTO with data that comes from the JSP will be with a method such buildDTO().
Tough, i'm sitill in doubt on how (WHERE) to implement this method.
I could ...
- place the buildDTO() method in the ActionForm.
OR
- place the buildDTO() method in the Action.
OR
- create a FormToDTOFactory class to perform the work, then i'll call it's methods from wherever i want.


What are your opinions?


Leandro Melo
SCJP 1.4, SCWCD 1.4
Jason Menard
Sheriff

Joined: Nov 09, 2000
Posts: 6450
I prefer to place a method like that in a separate helper class as opposed to the Action. I would never put something like that in an ActionForm.
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4456
    
    6

Originally posted by Jason Menard:
I prefer to place a method like that in a separate helper class as opposed to the Action. I would never put something like that in an ActionForm.


(Devil's advocate):

1) What's wrong with letting the ActionForm populate a DTO? One practice I have seen is to have a composite object in the ActionForm receive request parameter values. (Struts tags even support composite objects in the ActionForm by allowing the use of dot notation for property names). The composite object is then used as a DTO and passed on to the business layer. Is there anything wrong with this approach and how is it different from manually transferring request parameter values to a DTO in the ActionForm by way of a buildDTO() method in the ActionForm?

2) What is the advantage of delegating to a helper class as opposed to doing it from the Action?


Junilu - [How to Ask Questions] [How to Answer Questions]
Jason Menard
Sheriff

Joined: Nov 09, 2000
Posts: 6450
JL: What's wrong with letting the ActionForm populate a DTO?

While this is a style thing to be sure, the basic answer I would give is "that's not what they're for". I believe in strict separation of responsibilities. According to the Struts user guide:

An ActionForm represents an HTML form that the user interacts with over one or more pages.


To my mind, not only do DTO transfer methods (one method for each direction of transfer) not fit in with an ActionForm's role and responsibilities, they couple the class unnecessarily to the DTOs.

JL: One practice I have seen is to have a composite object in the ActionForm receive request parameter values. (Struts tags even support composite objects in the ActionForm by allowing the use of dot notation for property names). The composite object is then used as a DTO and passed on to the business layer. Is there anything wrong with this approach and how is it different from manually transferring request parameter values to a DTO in the ActionForm by way of a buildDTO() method in the ActionForm?

While you can certainly use composite objects in ActionForms, I prefer these composite objects to be in effect other ActionForms, or at least serve that same functionality. Remember the ActionForms are automatically populated from the request. That is, these objects are directly populated by user input. Therefore you must consider these objects tainted. As this is the case, you have to be very careful about passing it directly to your business object without the proper validation being done. To my way of thinking, Perl has it right with the whole tainted variable thing that forces you to perform validation on these things. That being said, it also goes back to the earlier point I made about preferring a clean separation of responsibilities. YMMV. The Struts User Guide has the following to say on the subject:

If you nest an existing bean instance on your form, think about the properties it exposes. Any public property on an ActionForm that accepts a single String value can be set with a query string. It may be useful to place beans that can affect the business state inside a thin "wrapper" that exposes only the properties required. This wrapper can also provide a filter to be sure runtime properties are not set to inappropriate values.


So yeah, you can do it. I simly prefer not to. While it saves you a tiny bit of code (minimal if you use BeanUtils), I feel it is a better and safer practice in general to maintain the separation. The point can certainly be argued though.

JL: What is the advantage of delegating to a helper class as opposed to doing it from the Action?

I just think it's cleaner, and it comes back to that whole separation of responsibilities thing. Say I have three DTOs (A, B, C), three associated forms, a create, update, and delete actions to go along with each of the three forms. The easy thing to do would be to have one base Action class that all the Actions extend which contain the transfer methods for each DTO/ActionForm pair. However, now I've got Actions with methods that don't really have any business being in the class. For example, if my Action only uses DTO/Form C, why should it have the methods for A and B? So then you say we have three different base classes and have each Action only exetend the specific Action class containing the oppulate methods. Ugh! Now it's starting to get messy.

Let's make the problem worse by throwing in some utility methods that all the Action classes need. So now I need to extend my implementation Action classes from the specific base Action containing the correct transfer methods, and that Action class has to be extended from the one containing my utility methods. It just seems unnecessary when you can just delegate the responsibilities of DTO/ActionForm transfer to a single helper class, maintaining the integrity of a clean design and separation of roles and responsibilities.

Again, this is just how I prefer to do things and you may quite disagree. In my experience keeping things separated, aside from providing a cleaner design, often saves more in maintenance than the few less lines of code it might take to not separate out this kind of stuff.
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4456
    
    6

First, I just want to make it clear that I'm not necessarily disagreeing with your position. I'm just trying to better understand the reasons behind it. I have seen a lot of variations in the way Struts applications are coded and each approach has its pros and cons. I'm just trying to sort out which approaches tend to cause more pain and sorrow than others and why.

JM: While this is a style thing to be sure, the basic answer I would give is "that's not what they're for". I believe in strict separation of responsibilities. According to the Struts user guide:

An ActionForm represents an HTML form that the user interacts with over one or more pages.


But isn't that just half of its responsibility? To review, an ActionForm exists for the following reasons:

1. To serve as an abstraction for the request parameters. Struts automatically matches request parameters and ActionForm properties. Struts also performs type conversion from String to the property's actual type whenever necessary.

2. Provide front-line validation of property values via the validate() method. There is often confusion as to what kind of validation should be performed in this method. To add to this confusion, an alternative method of validation is available in the validation framework.

3. To make the values obtained from the client request available to other tier(s) (control?, business?, persistence?).

JM: To my mind, not only do DTO transfer methods (one method for each direction of transfer) not fit in with an ActionForm's role and responsibilities, they couple the class unnecessarily to the DTOs.

OK, let's examine the kind of coupling that results with this approach. Obviously, we do not want to totally eliminate coupling since these objects need to work with each other. What we really want to do is manage the dependencies such that code changes have minimal collateral impact.

If you think about it, the ActionForm is already dependent on the underlying Model object at the attribute level because it represents some or all of the Model attributes. If you add an attribute to the model, the ActionForm is likely to require a change as well.

The Action is also dependent on the Model but at a higher level than the ActionForm. A change to the Model will not necessarily require a corresponding change in the Action.

Since the ActionForm is already coupled to the Model at the attribute level, would it be better to make the ActionForm responsible for stuffing the DTO that will be passed on to the Model? Doing so would concentrate the code that gets affected by changes to the Model in just one class: the ActionForm. Wouldn't this be a good thing?

If instead, we make a helper object responsible for extracting values from the ActionForm and stuffing a DTO, then won't we increase the number of dependencies within the application? That is, the helper class is now dependent on the ActionForm and the DTO and the ActionForm is now dependent on the ActionForm, the business object, and the helper.
[ June 10, 2004: Message edited by: Junilu Lacar ]
Leandro Melo
Ranch Hand

Joined: Mar 27, 2004
Posts: 401
Hy guys,
thanks for the rich discussion on the topic, although as i`m a very beginner at struts i might have a couple more questions.

I like Junilu`s point of view, the "coupling" you`d have by placing the buildDTO() method in the ActionForm has actually a minor impact on placing it in helper classes. So Junilu, you`d send the DTO to the Action just in a request.setAttribute(), right?

The whole discussion was made around placing the buildDTO() method either on ActionForm or in a helper class, but what about setting the DTO in the Action?
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4456
    
    6

Now hold yer horses there, Leandro. I go by the same principles as Jason: assign responsibilities properly, clean separation of concerns, loose coupling, and good OO design. I'm not recommending any approach at this point. Just trying to sort things out and make sure there's no Straw Man. I think maybe a concrete example is warranted at this point to help us get a clearer picture of how certain decisions affect our design.

Later...
Jason Menard
Sheriff

Joined: Nov 09, 2000
Posts: 6450
I didn't forget you Junilu. You raised some good points that I thought we could explore further.

JL: There is often confusion as to what kind of validation should be performed in this method.

Validation of user input only is performed in the ActionForm. For example, making sure a date is entered in the correct format. Business validation is handled in the business objects. Keeping with dates, if there is a business rule that says dates must be within a certain range of some other date, then that is something that would be validated by the business object.

JL: To make the values obtained from the client request available to other tier(s) (control?, business?, persistence?).

An ActionForm is a control object, so as I see it, it's only proper that the ActionForm pass data to other control objects (such as Actions) as well as business objects in instances where the data has been validated and cannot be considered tainted.

JL: If you think about it, the ActionForm is already dependent on the underlying Model object at the attribute level because it represents some or all of the Model attributes.

I would say that it is dependant on the view, not the model. The ActionForm passes data between the control and the view, and the model is somewhat irrelevant. Now it's true that we as programmers normally have a fairly tight mapping between the ActionForm and the model, but this is only to the extent that the model has data we wish to display in the view. I know what you're saying, I just think that this concept of coupling between the ActionForm and model is born out of convenience and somethig we impose on ourselves, rather than one that is imposed by the nature of the Struts architecture.

JL: Since the ActionForm is already coupled to the Model at the attribute level, would it be better to make the ActionForm responsible for stuffing the DTO that will be passed on to the Model? Doing so would concentrate the code that gets affected by changes to the Model in just one class: the ActionForm. Wouldn't this be a good thing?

I already argued the first part, that they aren't erally coupled, any more so than the entire application is coupled from view through controller through model simply because it is designed to display and process a specific set of data (if you change your model you may have to change your view). That aside, my objection to this is that we are forcing a coupling where it doesn't seem natural and giving the ActionForm responsibilities that it shouldn't have. Remember, good design dictates that objects should be pretty focused in their responsibilities. Why not have the Action perform this mapping (and I've done this in the past)? Why not the business object? It would seem arbitrary in my mind to force this. And it's for this reasno that I advocate a helper class.

JL: the ActionForm is now dependent on the ActionForm, the business object, and the helper.

I already argued the point that an ActionForm is dependant on the business object so we can skip that for now (feel free to rebut of course), but I'm not certain what you mean by the ActionForm being dependant on the helper. How so? The ActionForm certainly has no references to the helper or other wise calls any methods on it. On the other hand, the helper could certainly be dependant on the ActionForm and model though. Even that's not a certanity if your helper is something along the lines of BeanUtils.

By the way, let me add that I appreciate the debate. It livens things up around here.
[ June 16, 2004: Message edited by: Jason Menard ]
Leandro Melo
Ranch Hand

Joined: Mar 27, 2004
Posts: 401
Well, this has been a nice discussion. As a beginner, a really get a lot of knowledge from it.

Jason, i understand most things you said. Actually, i also thing that it's very dificult to decouple the Model from the View sometimes. Specially on that ActionForm thing... it just seems to be the "perfect" model!

However, i didn't quite understand the following statement of yours.

Originally posted by Jason Menard:
The ActionForm certainly has no references to the helper or other wise calls any methods on it. On the other hand, the helper could certainly be dependant on the ActionForm and model though. Even that's not a certanity if your helper is something along the lines of BeanUtils.



I don't get how the ActionForm would use a helper class if it doesn't call methods on it. Can you give a better explanation on this?
Jason Menard
Sheriff

Joined: Nov 09, 2000
Posts: 6450
Originally posted by Leandro Melo:
I don't get how the ActionForm would use a helper class if it doesn't call methods on it. Can you give a better explanation on this?


Because it's late and I can't think of a better name right now, let's call our helper class ModelViewMapper, and assume it has the following two methods:

ModelViewMapper
---------------
public static void copyToForm(ActionForm, Object)
public static void copyToDTO(Object, ActionForm)

You might use it something like this:

Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4456
    
    6

I didn't forget you Junilu.

It feels good to be remembered

An ActionForm is a control object

Actually, I think it's more of a View/Presentation side object. And I agree, it should handle initial type validation. One common problem I have seen is that there's often a tendency to overextend and do more in validate() or with the Validation Framework than just simple data "edits" (as they are called in some circles).

it's only proper that the ActionForm pass data to other control objects (such as Actions) as well as business objects in instances where the data has been validated and cannot be considered tainted.

Then wouldn't it also follow that it would be proper for the ActionForm to populate a Transfer Object for the objects in tiers below the Presentation to consume? I've been trying to see if using the OSI stack as a metaphor helps. Higher-level layers in the OSI stack can encapsulate/wrap data before passing it down to lower-level layers. Conversely, data is unwrapped as it goes back up the stack. If we take the Client as the highest level and the database as the lowest level, then the Presentation tier (high level) would wrap the Client input before passing it down to either the lower level control (Action) or business object.

JL: If you think about it, the ActionForm is already dependent on the underlying Model object...

JM: I would say that it is dependant on the view, not the model. The ActionForm passes data between the control and the view, and the model is somewhat irrelevant.

OK, I think I can buy that. If the view is changed, a corresponding change in the ActionForm is likely to be required while the model can remain unchanged. This kind of messes up my OSI stack metaphor though, since a layer are supposed to be dependent on only the layer directly below it. Or maybe not since the JSP and the ActionForm are both part of the View. Hmm, that would mean that if the JSP were to change so that the same data could be presented differently, any manipulation or massaging of the data should be handled by the ActionForm, not the Action or the Business Object.

JL: the ActionForm is now dependent on the ActionForm, the business object, and the helper.

My bad. I meant to write the Action is now dependent on the ActionForm, the business object, and the helper. Although come to think of it, that is still refutable.

By the way, let me add that I appreciate the debate. It livens things up around here.

So are you going to nominate this thread for the JavaRanch Radio then?

It's getting late here, I'll follow up later...
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: A buildDTO() in Action or in ActionForm ???