struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ted Husted <hus...@apache.org>
Subject Re: [Struts Tips] #2 - Template Method Dispatch Action?
Date Thu, 06 Jun 2002 12:21:28 GMT
Adding dispatch support to the ExecuteLogic() method does sound like an
interesting project for someone ...


"Molitor, Stephen" wrote:
> 
> Why are the Framework and Dispatch approaches mutually exclusive?  It seems
> like you could do both -- have a base action with extension points (hot
> spots), and the main hotspot method (i.e. 'executeLogic') could optionally
> be a dispatch method.  This would help with create/update/delete operations,
> where all the logic is the same except for which db operation to perform.
> Of course it's not the only way to do it -- the 'business bean' approach you
> mention, where the mapping specifies the business class, would also work
> nicely.  But the framework + dispatch approach could cut down on the number
> of classes (business bean or action).  The business bean and framework +
> approaches actually seem pretty similar to me.  The only difference is
> whether the main extension point is a separate class, or a method of the
> action class.  In either case the extension point is specified in the
> configuration file.
> 
> Steve Molitor
> 
> > I believe the Dispatch and Template (or Framework) class approaches may
> > be mutally exclusive. The idea of the Dispatch class is that you can
> > vector to an arbitrary method. The idea of a Framework class, like
> > SuperAction uses, is that a known entry method calls a number of
> > hotspots (or extension points) that you can override.
> 
> -----Original Message-----
> From: Ted Husted [mailto:husted@apache.org]
> Sent: Saturday, June 01, 2002 7:31 AM
> To: Struts Users Mailing List
> Subject: Re: [Struts Tips] #2 - Template Method Dispatch Action?
> 
> "Molitor, Stephen" wrote:
> > As is, the DispatchAction in Struts 1.02  cool, but does not provide
> direct
> > support for eliminating or consolidating duplicate code from related
> tasks.
> > It's just a different style.  With DispatchAction, one can have one big
> > action class to handle related tasks, as opposed to  several little Action
> > classes.  However, related tasks often have some common logic that needs
> to
> > be performed for all the tasks, and other logic that is specific to each
> > task.  It would be cool if there was a DispatchAction that provided hooks
> > for the common logic.
> 
> For something similar, see the SuperAction in the Scaffold package.
> 
> http://cvs.apache.org/viewcvs/jakarta-struts/contrib/scaffold/src/framework/
> main/org/apache/scaffold/http/SuperAction.java
> 
> I believe the Dispatch and Template (or Framework) class approaches may
> be mutally exclusive. The idea of the Dispatch class is that you can
> vector to an arbitrary method. The idea of a Framework class, like
> SuperAction uses, is that a known entry method calls a number of
> hotspots (or extension points) that you can override.
> 
> You could share common utility methods among various Dispatch methods by
> passing all needed parameters through the signature, but how to merge
> this idea with a framework class approach isn't jumping out at me.
> 
> The closest thing may to be use a relay action to forward the request to
> another Action based on a framework class. You then just override a
> business extension method on the framework Action (like
> SuperAction.ExecuteLogic). This doesn't reduce the number of Actions,
> but it does let you share as much code as possible
> 
> Personally, I use very few Struts Actions in an application. Instead I
> tend to specify a business class as part of the action mapping, and then
> have the Action call that, using a base Action like the above. The
> business beans have a hotspot method with a known signature. The Action
> just instantiates the business bean (like the ActionServlet instantiates
> a form bean), calls the signature, and copes with the result. (Just like
> the ActionServlet calls an Action.)
> 
> This trades Actions for business beans, but minimizes coupling to Struts
> and maximizes code reuse between platforms.
> 
> The Advanced Struts skeleton for Adalon, uses the same approach. (No
> surprise, I wrote it =:)
> 
> http://synthis.com/products/architectures/struts/
> 
> Synthis has released the skeleton code under the Apache License, and I'm
> integrating it back into the Scaffold package and updating the Artimus
> application to use the new clases. So, there will major updates to these
> next week. All the same ideas, but with some improvements to the
> implementation. Film at 11.
> 
> -- Ted Husted, Husted dot Com, Fairport NY US
> -- Developing Java Web Applications with Struts
> -- Tel: +1 585 737-3463
> -- Web: http://husted.com/about/services
> 
> "Molitor, Stephen" wrote:
> >
> > As is, the DispatchAction in Struts 1.02  cool, but does not provide
> direct
> > support for eliminating or consolidating duplicate code from related
> tasks.
> > It's just a different style.  With DispatchAction, one can have one big
> > action class to handle related tasks, as opposed to  several little Action
> > classes.  However, related tasks often have some common logic that needs
> to
> > be performed for all the tasks, and other logic that is specific to each
> > task.  It would be cool if there was a DispatchAction that provided hooks
> > for the common logic.  One approach would be to use the Template Method
> > pattern, perhaps something like this:
> >
> > public class TemplateMethodDispatchAction extends DispatchAction {
> >
> >   public ActionForward perform(ActionMapping mapping,
> >                                ActionForm form,
> >                                HttpServletRequest request,
> >                                HttpServletResponse response) {
> >     beforeHook();
> >     ActionForward forward = super.process(mapping, form, request,
> response);
> >     return afterHook(forward, mapping, form, request, response);
> >   }
> >
> >   protected void beforeHook(ActionMapping mapping,
> >                             ActionForm form,
> >                             HttpServletRequest request,
> >                             HttpServletResponse response) {
> >     // does nothing by default
> >   }
> >
> >   protected ActionForward afterHook(ActionForward forward,
> >                                     ActionMapping mapping,
> >                                     ActionForm form,
> >                                     HttpServletRequest request,
> >                                     HttpServletResponse response) {
> >     return forward; // just returns the forward that was passed in by
> > default
> >   }
> >
> > }
> >
> > Defing the beforeHook and afterHook methods in derived clases would be
> > optional.  If you don't define them, TemplateMethodDispatchAction behaves
> > just like DispatchAction.  If you choose to define them, you have slots to
> > put common pre/post processing logic.
> >
> > The afterHook method returns an ActionForward to allow for cases where the
> > logic to determine the next page is common for all tasks, and can thus be
> > coded in one place in the afterHook.  However, the default implementation
> of
> > afterHook just returns the forward returned by the task specific methods
> > (i.e. create, update, delete), to allow for cases where the logic to
> > determine the next page varies with the task.
> >
> > Of course, you can use procedural decomposition to factor out the common
> > logic instead, and rely on the task specific methods (i.e. create, update,
> > delete) to remember to call the appropriate pre/post processing methods at
> > the right time.  However, the calls to the common methods would still get
> > duplicated in each task specific method.  The Template Method approach is
> > more automated.
> >
> > Does Struts 1.1 have anything like this?
> >
> > Steve Molitor
> > smolitor@erac.com
> >
> > -----Original Message-----
> > From: Ted Husted [mailto:husted@apache.org]
> > Sent: Friday, May 31, 2002 6:12 AM
> > To: struts-user@jakarta.apache.org
> > Subject: [Struts Tips] #2 - Use DispatchAction to organize related
> > operations
> >
> > Any software application is defined by the things it can do for you. In
> > a Struts Web application, the things an application does is usually
> > defined by its action-mapping elements. An action-mapping is designed to
> > be the target of an HTML form, and is often used with hyperlinks as
> > well.
> >
> > Each action-mapping can specify a Struts Action class as its handler. In
> > larger applications, developers can find themselves managing dozens or
> > even hundreds of Action classes.
> >
> > In practice, many of these Action classes handle related operations,
> > often evidenced by their name. A package might include separate
> > RegCreate, RegSave, and RegDelete Actions, which just perform different
> > operations on the same RegBean object. Since all of these operations are
> > usually handled by the same JSP page, it would be handy to also have
> > them handled by the same Struts Action.
> >
> > A very simple way to do this is to have the submit button modify a field
> > in the form which indicates which operation to perform.
> >
> > <SCRIPT>
> > function set(target) {
> >  document.forms[0].dispatch.value=target;
> > }
> > </SCRIPT>
> >
> > <html:hidden property="dispatch" value="error"/>
> > <html:submit onclick="set('save');">SAVE</html:submit>
> > <html:submit onclick="set('create');">SAVE AS NEW</html:submitl>
> > <html:submit onclick="set('delete);">DELETE</html:submit>
> >
> > Then, in the Action you can setup different methods to handle the
> > different operations, and branch to one or the other depending on which
> > value is passed in the dispatch field.
> >
> > String dispatch = myForm.getDispatch();
> >
> > if ("create".equals(dispatch)) { ...
> >
> > if ("save".equals(dispatch)) { ...
> >
> > The Struts Dispatch Action is designed to do exactly the same thing, but
> > without messy branching logic. The base perform method will check a
> > dispatch field for you, and invoke the indicated method. The only catch
> > is that the dispatch methods must use the same signature as perform.
> > This is a very modest requirement, since in practice you usually end up
> > doing that anyway.
> >
> > To convert an Action that was switching on a dispatch field to a
> > DispatchAction, you simply need to create methods like this
> >
> >     public ActionForward create(ActionMapping mapping,
> >                  ActionForm form,
> >                  HttpServletRequest request,
> >                  HttpServletResponse response)
> >     throws IOException, ServletException { ...
> >
> >     public ActionForward save(ActionMapping mapping,
> >                  ActionForm form,
> >                  HttpServletRequest request,
> >                  HttpServletResponse response)
> >     throws IOException, ServletException { ...
> >
> > Cool. But do you have to use a property named dispatch? No, you don't.
> > The other step is to specify the name of of the "dispatch" property as
> > the "parameter" property of the action-mapping. So a mapping for our
> > example might look like this:
> >
> >             <action
> >                 path="/reg/dispatch"
> >                 type="app.reg.RegDispatch"
> >                 name="regForm"
> >                 scope="request"
> >                 validate="true"
> >                 parameter="dispatch"/> // Which parameter to use
> >
> > If you wanted to use the property "o" instead, as in o=create, you would
> > change the mapping to
> >
> >             <action
> >                 path="/reg/dispatch"
> >                 type="app.reg.RegDispatch"
> >                 name="regForm"
> >                 scope="request"
> >                 validate="true"
> >                 parameter="o"/> // Look for o=dispatchMethod
> >
> > Again, very cool. But why use a JavaScript button in the first place?
> > Why not use several buttons named "dispatch" and use the values to
> > specify the operation.
> >
> > You can, but the value of the button is also its label. This means if
> > the page designers want to label the button something different, they
> > have to coordinate with the Action programmer. Worse, localization
> > becomes virtualy impossible.
> >
> > If you prefer not to use JavaScript buttons, you can use the
> > DispatchLookup Action instead. This works much like the DispatchAction,
> > but requires more setup. We'll explore the DispatchLookup Action in Tip
> > #3.
> >
> > HTH, Ted.
> >
> > ---
> >
> > Struts Tips premiere twice weekly on the MVC-Programmers List. To
> > subscribe, visit BaseBean Engineering < http://www.basebeans.com >.
> >
> > An archive of past tips, like this one, is available at <
> > http://jguru.com/faq/subtopic.jsp?topicID=893704 >.
> >
> > About Ted. Ted Husted is an active Struts Committer. He also moderates
> > the Struts mailing list and the JGuru Struts
> > FAQ.
> >
> > Copyright Ted Husted 2002. All rights reserved.
> >
> > _______________________________________________
> > MVC-Programmers mailing list
> > MVC-Programmers@basebeans.com
> > http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

--
To unsubscribe, e-mail:   <mailto:struts-user-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:struts-user-help@jakarta.apache.org>


Mime
View raw message