I find this discussion a bit confusing.  Is this about the supplanting
of implementation code of RequestProcessor with a chain?  Is this
about adding condition support in commons-chain to commons-chain or to
Struts?  I will assume the latter.  Accordingly, I will assume that
"chain" means "struts-chain".

If I understand things correctly, there are other alternatives than
Don suggests.  My thing, of course, is that the "other alternatives"
are preferrable.  I would suggest, at a minimum, that there be a
standard plumbing chain.  If someone wants to change that and to use
XML, I would strongly suggest that that plumbing XML be kept strictly
separate from the application struts-config.xml file.

Actually, I would prefer that the conditional options be in the
implementation of an IoC RequestProcessor interface.  I would also, of
course, prefer that the Strategy Pattern:


public class InterfaceDefaultImplementation implements Interface {
  private Helper helper;
  
  public void setHelper(Helper helper) {
    this.helper = helper;
  }
  
  public void doSomething() {
    //... do something
    int value = helper.doIt(args);
    //... do more
  }
}

be preferred over the Template Method Pattern:

public abstract class AbstractInferface implements Interface {
  public void doSomething() {
    //... do something
    int value = doIt(args);
    //... do more
  }
  
  protected abstract int doIt(params);
  
  public class InterfaceDefaultImplementation extends AbstractInterface {
    protected int doIt(params) {
      //....
    }
  }
}

The advantages are: 

-- ONE: we can change the strategy at runtime do to the flexibility of
composition over inheritance.

-- TWO: the implementations are not linked and we can pick and mix
different strategy implemenations in any combination.

-- THREE: we can use the same strategy interface in multiple classes
allowing for the sort of flexibility that you get from commands in
chains.

-- FOUR: we can test using mock objects.

(This is all well-known, of course, and not original.  I hope I am not
out of bounds reminding anyone of these benefits.)  I probably won't
have much to say on this after this, since it does not seem to appeal
to anyone in particular.
  

<snip no='A'>
On Sun, 20 Feb 2005 10:26:14 -0800, Don Brown <[EMAIL PROTECTED]> wrote:
> Ah, we finally stumble onto the very slipperly slope that is conditional
> support for commons-chain.  As we put more and more code into chain, we
> will inevitably have commands that only need to execute under certain
> conditions.  There are three possibilities:
</snip>

Great that this discussion comes at this point.  Measure twice: cut once!

<snip no='A1-'>
>   1. Bury conditional logic inside the command itself.  This is the
> approach many of the current chains take, but has the disadvantage of
> the flow being very unclear to the reader of the config file, requiring
> digging into the source code.
</snip>

Since this is Struts plumbing, is this really a disadvantage?  And,
isn't this part of the plumbing merely implementation?  Should this
code dictate architecture.

<snip no='A-2'>
>   2. Create an "if" command, which then would logically lead to a
> "switch" command and perhaps a "for" command.  These commands would
> check certain conditions then execute configured commands based on the
> outcome.
</snip>



<snip no='A-3'>
>   3. Modify the XML so that the branching code is described as XML
> elements.  While this option produces the clearest code, it also brings
> all the problems of something like Jelly with it.
</snip>

For my part, using XML for implementation is baroque.


> So far, chain has resisted conditional support for the very reason it
> opens up a huge can of worms.  However, as soon as you start putting
> complex logic in commons-chain, you are going to run up against the
> problem again and again, and I think solution 1 will really start to be
> inadequate.  Solution 2 feels like a hack, and solution 3 (executable
> XML) has been shown a bad idea through Jelly.
> 
> I wonder what a merging of commons-chain and a scripting language like
> beanshell would look like...
> 
> Don
> 
> Joe Germuska wrote:
> > At 10:00 AM -0800 2/18/05, Don Brown wrote:
> >
> >> I think the WebWork2/XWork implementation of interceptors is pretty
> >> spot on.  You define interceptors and interceptor stacks at the top of
> >> your configuration file.  Then, in the action mapping, we'd add an
> >> attribute called say "interceptor" which would be the name of an
> >> interceptor stack or interceptor.  We could use "pre" and "post", but
> >> post is really just an interceptor that only contains code on the
> >> response.
> >>
> >> However, since we already have this commons-chain framework,  perhaps
> >> all we need is the "interceptor" attribute that would point to a chain
> >> command.  Chain supports the notions of Filters and is more robust in
> >> that interceptor stacks or chains could have child chains, etc.
> >
> >
> > This may be a reason for pushing in a direction I'd been mulling but
> > hadn't implemented: break up "process-action" into parts.  I don't like
> > that everything after ValidateActionForm needs to have a hard-coded
> > "check if form was valid" test; that shouldn't be built into the
> > command, but rather should be part of the chain design.  So maybe from a
> > big picture,
> >
> > In short form, here's what it is now:
> >
> > servlet-standard (chain command):
> >    command: ExceptionCatcher
> >    lookup: process-action
> >    lookup: process-view
> >
> > into something like this:
> > servlet-standard (chain command):
> >    command: ExceptionCatcher
> >    lookup: preprocess-action
> >    lookup: process-form
> >    conditional lookup: process-invalid-form
> >    conditional lookup: process-valid-form
> >    lookup: process-view
> >
> > where the current process-action would break down like this:
> >
> > "preprocess-action"
> >    lookup: servlet-standard-preprocess
> >    command: SelectLocale
> >    command: RequestNoCache
> >    command: SetContentType
> >    command: SelectAction
> >    command: AuthorizeAction
> >
> > "process-form"
> >    command: CreateActionForm
> >    command: PopulateActionForm
> >    command: ValidateActionForm
> >
> > "process-invalid-form"
> >    command: SelectInput
> >
> > "process-valid-form"
> >    command: ExecuteCommand
> >    command: SelectForward
> >    command: SelectInclude
> >    command: PerformInclude
> >    command: CreateAction
> >    command: ExecuteAction
> >
> > In that case, the "process-valid-form" could be wrapped in the
> > interceptor (or do you also want to intercept the form part?)
> >
> > It seems like it would be pretty easy to write a variant of the Chain
> > class which, when given an interceptor map, could use the name of each
> > command it found to look for a registered interceptor, and use it to
> > wrap the command.  Except for your concern about avoiding putting things
> > in the context, this seems like it might be a good candidate for
> > inclusion in the core commons-chain library.  Perhaps a base
> > implementation could go there, and it could be elaborated for dependency
> > injection.
> >
> > All of this sounds like a good candidate for Struts.SF.net for the
> > foreseeable future...
> >
> > Joe
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 


-- 
"You can lead a horse to water but you cannot make it float on its back."
"Heaven has changed.  The Sky now goes all the way to our feet.

~Dakota Jack~

"This message may contain confidential and/or privileged information.
If you are not the addressee or authorized to receive this for the
addressee, you must not use, copy, disclose, or take any action based
on this message or any information herein. If you have received this
message in error, please advise the sender immediately by reply e-mail
and delete this message. Thank you for your cooperation."

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to