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