struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ted Husted <hus...@apache.org>
Subject Re: too many Action classes
Date Fri, 28 Sep 2001 13:30:52 GMT
If an applicaton is properly "normalized", meaning the business logic is
expressed in beans that are not tied to the Web tier, then how many
Actions you need comes down to how many sets of local forwards you want.
This implies that you need an Action for each of your application's
"workflows".

An Action class should be a simple adapter that is responsible for
handling navigation flow, including error handling. It should just be
calling business logic beans, and analyzing the result.

Using the parameter property, it is very easy to get a single Action to
handle several operations. Just specify the operation as the parameter
property, and look for that in your Action. 

Here's a utility method from a class that handles CRUD operations. The
Helper bean does most of the real work. A different helper can be
created for different tables, and this one action can handle all the
CRUD for an application ;-). Just subclass, and provide a different
helper bean. Note that all it does is analyze the results; it doesn't do
any actual work. Dispatch is the parameter property. 

    public int crud(
        ActionMapping mapping,
        DataBean thisForm,
        HttpServletRequest request,
        ActionErrors errors,
        Object confirm[],
        AccessBean thisHelper
        )
    {
        // -- Snag parameters
        thisHelper.set(
            request.getParameter(DataAccess.KEY),
            request.getParameter(DataAccess.COLUMN),
            getDispatch(mapping,request),
            SMART_STORE
        );

        // -- Validate dispatch operation
        if (!thisHelper.isDispatchValid()) {
            errors.add(ActionErrors.GLOBAL_ERROR,
                new ActionError("action.missing.parameter"));
        }

        // -- Main block
        int result = 0;
        String dispatch = thisHelper.getDispatch();
        if (errors.empty()) try {

            // -- INPUT ---
           if (DataAccess.INPUT.equals(dispatch)) {
                result = 1; // move on
            }

            // -- INSERT --
           if (DataAccess.INSERT.equals(dispatch)) {
                result = thisHelper.insert();
                if (result==0) {
                    confirm[0] = "sql.access.error";
                }
                else {
                    confirm[0] = "sql.record.inserted";
                    confirm[1] = thisForm.getKey();
                }
            }

             // -- SELECT --
            if (DataAccess.SELECT.equals(dispatch)) {
               result = thisHelper.select();
                if (result!=0) {
                    thisForm.set( thisHelper.toMap() );
                }
            }

            // -- UPDATE --
           if (DataAccess.UPDATE.equals(dispatch)) {
                result = thisHelper.update();
                if (result==0) {
                    confirm[0] = "sql.access.error";
                }
                else {
                    confirm[0] = "sql.record.updated";
                    confirm[1] = thisForm.getKey();
                }
            }

            // -- DELETE --
           if (DataAccess.DELETE.equals(dispatch)) {
                result = thisHelper.delete();
                if (result==0) {
                    confirm[0] = "sql.access.error";
                }
                else {
                    confirm[0] = "sql.record.deleted";
                    confirm[1] = thisForm.getKey();
                }
            }

            // Any takers?
            if (result==0) {
                errors.add(ActionErrors.GLOBAL_ERROR,
                    new ActionError("sql.access.empty"));
            }
            else {
                // Pass result in request
                request.setAttribute(AccessBean.HELPER_KEY,thisHelper);
            }

        } // end try

        catch(Throwable t) {
            // Log exception and post error message
            servlet.log("Exception: ", t );
            errors.add(ActionErrors.GLOBAL_ERROR,
                new ActionError("sql.access.error")); // probably
        }

        return result;
    }

A calling Action then boils down to this:

        // -- isCancelled?
        if (isCancelled(request))
            return (mapping.findForward("cancel"));

        // -- Usual prerequisites
        ActionErrors errors = new ActionErrors();
        ArticleForm thisForm = (ArticleForm) form;
        String[] confirm = new String[Access.CONFIRM_MAX]; // 4 in
Struts 1.0

        // -- data access operation --

             // -- Create data access value object
             // -- This could also be a collection of forms
            ArticleHelper thisHelper = new ArticleHelper(form);

            // ** Pass state to ancestor utility method **
            int result = crud(
                mapping,thisForm,request,errors,confirm,thisHelper);

        // -- Report any errors
        if (!errors.empty()) {
            saveErrors(request, errors);
            if (mapping.getInput()!=null)
                return (new ActionForward(mapping.getInput()));
            // If no input page, use error forwarding
            return (mapping.findForward("error"));
        }

        // -- Check for confirmations (ancestor method)
        saveConfirm(errors,confirm);

        // -- Save any confirmations
        if (!errors.empty())
            saveErrors(request, errors);

        return (mapping.findForward("continue"));

    } // end Perform

} // end Client

If I really wanted to minimize the number of Actions, I could use a
DispatchAction (see Javadocs) here instead, and route all the CRUD
operations through the single Action.

My feeling is that the best practice is to try and minimize the number
of Action classes, since these are instantiated and (as it stands) never
released. Use as many as you need, but no more ;-)

-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel +1 716 737-3463
-- http://www.husted.com/about/struts/

peter wrote:
> 
> Hi again
> 
> I'm relatively new to struts and am in the process of building my first real
> struts web app.  I'm finding though that I'm building lots and lots of
> Action classes.  My question is:
> 
> Is it better practise to try and use as few Action classes as possible, i.e
> to try and get each Action class to handle as many form processing
> transactions as possible?
> 
> As an aside I'd like to add (what I hope) is my first helpful comment to
> this mailing list.  My advice to anyone new to struts is to plan a struts
> app architecture and then implement a bare-bones version of it.  I've
> written loads of Action classes, form beans and .jsp pages that contan the
> minimal amount of functionality required, e.g my Action classes do nothing
> but forward control to another part of my application.  This has helped me
> to get used to reconfiguring the struts-config.xml file, and understanding
> the relationships between the model, view and controller components.
> 
> hope this helps
> 
> Peter

Mime
View raw message