A related thought,

On a previous project using a framework similar to struts we used both
explicit mapping (similar to the xml mapping provided by struts) and
implicit mapping of requests.  In the implicit mode, requests that were not
explicitly mapped to an action went through an implicit mapping.  For
example, if research-Articles.do was not explicitly mapped the action
servlet would attempt to find a XXX.research.ArticlesAction where XXX
represents the package base (e.g. org.apache.struts) for your application.

Although implicit mapping does not reduce the number of Action classes, it
simplify the struts-config.xml file by reducing the need for explicit
mappings for each action.

-----Original Message-----
From: DONNIE HALE [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, March 07, 2001 3:28 PM
To: [EMAIL PROTECTED]
Subject: RE: Minimizing Action class proliferation


Bill,

Thanks for responding. I understand what you're saying re: keeping the
action classes simple. However, it still makes the whole cycle more tedious
than perhaps it needs to be. It's harder to write "helper" methods, perhaps
for bean manipulation, that can be shared across action classes. In the real
world, where revision control is being used, you have to make sure to check
all the action classes in. And so on. Further, the smaller those action
classes are, the more painful it is to have to put each in a separate source
file.

I did answer my own question regarding nested classes, and perhaps came up
with a design pattern in the process. I've successfully used nested classes
as action classes:

public class SampleActions {

    public static class Step1 extends Action {

        public ActionForward perform(
            ActionMapping mapping,
            ActionForm form,
            HttpServletRequest req,
            HttpServletResponse res) throws java.io.IOException,
ServletException
        {
            SampleFormBean b = (SampleFormBean) form;

            // whatever

            return mapping.findForward("next");
        }
    }

    public static class Step2 extends Action {

        public ActionForward perform(
            ActionMapping mapping,
            ActionForm form,
            HttpServletRequest req,
            HttpServletResponse res) throws java.io.IOException,
ServletException
        {
            SampleFormBean b = (SampleFormBean) form;

            // whatever

            return mapping.findForward("next");
        }
    }
    
}

The only trick is that you have to specify the "type" attribute in
struts-config.xml as "package.OuterClass$InnerClass" (note the '$' qualifier
rather than a '.'). My not-yet-fully-formed thinking is to represent all
action classes which have the same "name" attribute (the form bean) as
nested classes in the same outer class. There may be a better way to
determine what actions should be considered "related".

Donnie


>>> [EMAIL PROTECTED] 03/07/01 02:11PM >>>
I know what you're saying, but hopefully your action classes are small, and
you haven't emulated the example application, which places business logic in
the Action class. That stuff should be in separate business logic beans
(code to do the database access, business logic, etc). Maybe that's what
you've missed. There's going to be an Action class for each type of action
the user can do, pretty much, but they should only perform that 'traffic
cop' functionality of using the business logic beans to do the work,
forwarding to the next appropriate page, trapping/logging any exceptions,
etc.

Bill Hines
Hershey Foods

-----Original Message-----
From: DONNIE HALE [mailto:[EMAIL PROTECTED]] 
Sent: Wednesday, March 07, 2001 11:25 AM
To: [EMAIL PROTECTED] 
Subject: Minimizing Action class proliferation

I'm certainly not the most experienced Struts person around, so weigh my
opinions accordingly. However, it's repeatedly occurred to me that one of
the "barriers to entry", so to speak, of using Struts is the rapidity with
which Action classes proliferate. The project we're working on, which will
eventually be fairly large but so far isn't, has dozens of Action classes.
It approaches one per page that could be displayed.

Perhaps there's a design pattern that we've missed which would alleviate
this. But apart from looking at the request path during "perform" and then
acting conditionally, which is very brute force, I don't see a lot of
options. I believe it would be preferable to have a single Action class in
which all related activity occurs. This makes it easier to add new "logical"
actions. More importantly, however, it greatly eases maintenance in the case
where you need to change a lot of related/similar code (maybe a back-end API
changed).

Here's one question: Would it work to specify an inner class as the "type"
for an action? For example (pseudocode):

public class OrderActions
{
    public class Query extends ActionBase
    {
        ActionMapping perform( ... )
    }

    public class Edit extends ActionBase
    {
        ActionMapping perform( ... )
    }

    public class Save extends ActionBase
    {
        ActionMapping perform( ... )
    }
}

I think you get the point.

Assuming that I'm not completely missing something, here's what I'm thinking
of as an enhancement. Add a "method" attribute to the "action" element in
struts-config.xml. If present, the ActionServlet would call this method
(using introspection or whatever makes sense); if it's not present, then
call "perform" as we do now; if the attribute is specified but the method
doesn't exists, it's an exception.

Thoughts???

Thanks,

Donnie

Reply via email to