The previous response was thought provoking and may answer my specific
concerns, but I don't see my way through the issues yet.
Let me be more specific so that we can dive into the issues that I face:
Currently, we have developed a full featured demo with two main wizards
-
1) Account Maintenance (4 screens)
2) Order Management ( 8 main screens with ~20 minor screens)
We have an Account Maintenance Form (about 50 properties) and an Order
form (about 250 properties).
Each Account Maintenance screen has its' own Action class feeding a
segment of the Account Maintenance Form.
The Order Management wizard has one main Action class with a couple of
helper classes to manage the 8 main screens (work flow) all feeding the
Order Form. The Order Form is also feed by a the 20 minor screens which
each have their own small Action class.
One of the minor Order screens is the Corporate Info screen (mainly
address info)- it is designed to be a popup screen that can be called
from within the Order wizard or the Account Maintenance wizard. However,
it isn't implemented as an independent Action/Form because we don't know
how to make the Order Form AND the Account Mntc Form both reuse the
Corporate Info Form/Action. Specifically, we don't know how to implement
such that the Action class for Corporate Info can be reused by both the
Order and Account wizards. So, today the same fields are duplicated in
the two wizards and all the code is duplicated (ugly!).
We can envision a wrapper form that contains other forms and uses a dot
notation in the JSPs to reference properties
(orderForm.corporateInfoForm.address) but how do the Action classes for
CorporateInfo get reused? There seems to be such tight coupling between
an ActionForm and an Action Class that I don't know how to achieve
reuse. I played with creating an IAddress Action interface that both the
Order and Account wizards could implement but got caught up in the
coupling issues.
Thanks!
...Steve
-----Original Message-----
From: Ted Husted [mailto:[EMAIL PROTECTED]]
Sent: Sunday, July 22, 2001 3:19 PM
To: [EMAIL PROTECTED]
Subject: Re: code reuse
I would say that if you have one EJB for all these properties, then you
should have one ActionForm as well.
The trick to ActionForm reuse is the validation method. If the class is
used on more than one form, then validate() may need to address a
different set of properties. If you are using the ValidatorForm, it has
a "page" property. Each formset can have its own page name, and can
validate only the properties relevant to that formset. Otherwise,
validate() is passed the ActionMapping, and you can use that to
determine your own form sets. Some developers also use hidden fields for
the same purpose.
Of course, if only one form is used for data-entry, validating more than
one form may not be an issue.
Once you have an ActionForm that you can use on more than one form, you
can also use the same Action to handle them all. Since Actions are
multithreaded and cached by the framework, fewer Actions can mean a
better deployment.
I'm often tempted to try designing an application around a single
ActionForm and Action. This may make for a more efficient Struts
application, but may also lead to maintenance issues.
In general, I tend to design my applications around "packages" or
modules. The package may offer several operations and JSP views, but use
only one Action and ActionForm for them all.
My favorite way to use an Action with several operations is to use a
separate ActionMapping for each. An easy way to tell one mapping during
processing from another is to use the parameter property to give each a
logical name.
<action
parameter="select"
path="/donor/Search"
type="org.wxxi.gavel.donor.http.Client"
name="donorForm"
scope="request"
validate="false">
<forward
name="continue"
path="/WEB-INF/pages/donor/Result.jsp"/>
</action>
<action
parameter="select"
path="/donor/View"
type="org.wxxi.gavel.donor.http.Client"
name="donorForm"
scope="request"
validate="false">
<forward
name="continue"
path="/WEB-INF/pages/donor/View.jsp"/>
</action>
In perform() or validate(), you can call mapping.getParameter(), and
call the appropriate operation.
The parameter property was originally introduced to support the optional
DispatchAction class. This uses reflection to call a different perform()
method for each operation. This is a nifty feature, and I do something
similar by subclassing Actions and giving the ancestors a utility
method to handle stadnard operators, across a package or even the
entire application.
The current DispatchAction expects the Action to be called using a
syntax like
http://localhost:8080/myapp/saveSubscription.do?method=update
where "method" is set as the parameter property.
The Action then dispatches this call to a public method with the
signature
public ActionForward update(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws
IOException,
ServletException
As soon as I find a good chance to use DispatchAction, I may try an
alternative that uses the parameter for the operation name, so the
syntax would be
http://localhost:8080/myapp/updateSubscription.do
with "update" given as as the parameter. (I prefer minimize reliance on
query strings and hidden fields.)
Of course, both the ActionForm and the Action are straight-forward Java
classes, and developers are encouraged to create ancestor classes for
common behaviours when applicable. Subclassing the ActionServlet to
reuse code is another common strategy.
Speaking of subclassing, you can also often reuse an Action to handle
various ActionForms throughout your application. For example, a single
one-line InputAction can be used to seed all of your input forms:
return (new ActionForward(mapping.getInput()));
You can InputAction from any mapping, using any ActionForm, and the
result will be a blank form, ready for data entry. Which ActionForm
is instantiated and what page is used for input is controlled by the
mapping, not the Action itself.
-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel 716 737-3463.
-- http://www.husted.com/about/struts/
> Steve LeClair wrote:
>
> Our firm is has been using the struts framework to build our
> application demos. Now that we are shifting into a development cycle
> for a production release, we'd like to know more about how to build
> the struts side of our codebase with reuse in mind.
>
> Has anyone collected threads on reuse strategies?
>
> For instance, in the demo we display/update coporate Address
> information on the Order form, on the Account Maintenance form and
> also in a popup (independent) form. Now it seems silly to have three
> sets of form/action classes to manage the same data (at least we only
> use one EJB ;>)
>
> Advice?
>
> Thanks...Steve