views:

336

answers:

2

Design question for using Business Objects as formBackingObjects in a Spring SimpleFormController.

Our controller's responsibility is to allow an End User to add a new Business Object to our web application.

So we are passing our Business Object though the formBackingObject(HttpServletRequest request) method. However, we've run into a conundrum.

The factory that we are using to create our new Business Object enforces the business rules that some of the attributes cannot be null. But since we don't know what the End User wants to enter we've been passing in "reasonable defaults" like "Please enter the name you want", but that seems hackie/icky at best.

What is a developer to do? I feel as though this is the classic chicken/egg problem.

All our Business Object are based off of Interfaces, should we create a Stub that represents the Business Object, pass the Stub as the formBackingObject, and then pass the Stub to the Factory on a Form submit? Or should we not pass anything in the formBackingObject and then manually gather the submitted information from the request?

Any other reasonable ideas/patterns?

Thank you for your time.

+1  A: 

I definitely wouldn't choose the option of not using a formBackingObject and gathering the information manually -- that would eliminate a lot of the power that makes Spring MVC worthwhile in the first place.

If I were you, I would just make a new factory, or factory method, that is designed specifically to create an "uninitialized" business object, and use that as your formBackingObject.

Another approach that is widely used is not to use a business object as your formBackingObject at all, but create a separate transport object whose only purpose is to be the formBackingObject (and then add a factory method for your business object that lets you initialize it from the transport object). One of the big advantages of this is if your business object has a deep tree of other objects inside it, this can make it a pain to use as a formBackingObject. If you create a separate transport object just for use as a formBackingObject, you can give it a much flatter structure.

JacobM
So, I'm pretty AOK moving forward with the idea of using an uninitialized business object or using a transport object, but how is using a transport object or a dead simple POJO (from matt b's post) different then using an ActionForm in struts? At some point we're going to have to pull information from the transport/POJO and put it into our hibernate based business object implementation classes. The only reason I ask is because I remember this as a major selling point of spring. I appreciate not having to extend ActionForm, but the outcome and behavior seems the same to me.
hooknc
It's a fair point. Myself, I prefer using the business object as the formBackingObject for this reason. On the other hand, it's not like the code to move the data from one object to the other is going to be so complicated. One place where this approach might make sense would be if you had a complex business object where each form only populated a part of it.
JacobM
+1  A: 

Use a command object (a dead simple POJO) to represent the user's input to your controller. Then you can use the validation built-in to Spring MVC to make sure that all of the required fields are supplied in the command object. If the command passes validation, then you can map it to a your "Business Object" programatically (or using a bean mapping library like Dozer).

This way you can handle validation, incomplete user submissions, etc., without touching or modifying any existing business logic / rules / service classes. This allows you to keep the web layer separate from these existing layers.

For reference, see the MVC tutorial, which touches on validation and command objects in Part 4.

matt b