Jing Zhou wrote:

It's not so much about "complexity" as it is readability.



The "complexity" in my message refers to the verboseness of the chain-config.xml file. What I am looking for is a possible simpler syntax to do the job.



If I care what Process Action is then I can see the detail.  Goto's
were deemed dangerous because of the behavior that they hide.  They
obfuscate the flow of the code.  It's not really any different here
either.



<command jumpLabel="L1" className="Class1" />
<command jumpLabel="L2" className="Class2" />
<command label="L1" className="Class3" />
<command label="L2" className="Class4" />


I had a longer response prepared to your other post, but decided it
was too wordy. :) One example where the obfuscation comes in is that
I had to look at it for a bit before determining that Class4 was always run. If a few more commands are thrown in, it really gets
confusing.



You do not need to determine Class4 was always run or not,
actually it is determined at runtime. Its definition is included in every labeled chain by default.


It is absolutely necessary to understand the control flow if you want to customize it. The above would support all of the following flows (assuming that no command returns true prematurely):
* Class1 - Class2 - Class3 - Class4
* Class1 - Class3 - Class4
* Class1 - Class2 - Class4


Now, if I want to add a new step that has to occur before Class3, but is ONLY executed if Class3 will be executed, how do I do that? I have to change which command gets label L1, which is bad for the same reason that "goto" in programming languages is bad.


The idea is that you do not have to define a separate chain else where
if you could re-use a labeled chain in the current chain definition.
You could also ignore labels if any, just use the chain as is.


If you're going to (potentially) ignore the labels and branches, why have them in the first place?

Or, to put it differently, conditional behavior should be a feature of the Command implementation ("is the world in the correct state for me to perform this action?"). If the current state is not correct, it should just return false to let the chain continue. That's why a change based on Ted's suggestion:

(1) LookupCommand
(2) ExceptionCatcher
(3) SelectLocale
(4) SelectAction
(5) CreateActionForm
(6) PopulateActionForm
(7) ValidateActionForm (must save state in the Context)
(NEW) SelectInput [skip if validation succeeded]
(8) CreateAction [skip if validation failed]
(9) ExecuteAction [skip if validation failed]
(10) PerformForward

is actually the cleanest overall approach. The user should not have to even *know* what conditions the commands care about to determine whether they are executed. Thus, you would end up with a clean and simple chain definition:

<chain id="request-processor">
 <command class="LookupCommand"/>
 <command class="ExceptionCatcher"/>
 <command class="SelectLocale"/>
 <command class="SelectAction"/>
 <command class="CreateActionForm"/>
 <command class="PopulateActionForm"/>
 <command class="ValidateActionForm"/>
 <command class="SelectInput"/>
 <command class="CreateAction"/>
 <command class="ExecuteAction"/>
 <command class="PerformForward"/>
</chain>

Now, if I want to insert something that always happens before ValidateActionForm, I know exactly where it goes. I don't have to worry about whether ValidateActionForm is going to branch or skip, because it's not ... SelectInput and friends decide for themselves whether they are relevant.

OK, I've convinced myself that this is the right approach :-). So I'll likely be changing struts-chain to this tonight, and adding the appropriate mechanisms for ValidateActionForm to pass on the success or failure state information.



-Paul




Jing


Craig



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



Reply via email to