For me, "Simple thing should be simple" is the
top rule that supersedes any programming practices.
Some of might say that this *is* a programming practice. Some might also couch it as start with "the simplest thing that can possibly work", and then let practice be your guide.
* If I have 15 commands that needs to jump to the last one in a chain, if the branch way is used, then the last command must be repeatedly defined16 times in the config file. It loses the grace in expressions (although the sample config file does not reveal this problem).
Each Command can examine the Context to see if it can handle the current state. If it can't then it returns false, and processing continues. You don't need to "jump", you need a Command to define the appropriate state in your Context.
The fundamental problem might be viewing the Chain as the brains of the operation. It isn't. The Chain is just a composite of Commands. The Context manages state, and so the Context is where any decision making occurs.
* The "branch behavior" and "jump behavior" are complementary to to each other in theory. Repeatedly executing a set of commands in a chain can not be done gracefully in a *extreme* configurable chain.
Yes, it's possible that the branch behavior might not be the best way to go. I suspect that it might be better if a Command did not call other Commands, either directly or through the Catalog. But, I do think we should leave that door open so that people can experiment with this extension. I know in similar implementations, I often found myself having (the equivalent of) Commands calling Commands. But those implementations did not have a Chain to work with, and once we have more experience working with a real Chains, other strategies may become evident. I believe that at some point we may be able to dispense with branch behavior, so that very little happens behind the scenes. Or maybe not. Practice will dictate.
* Basing index values for "jump behavior" is fundamentally flawed.I was aware of that. It has the similar problems as in the pseudo controllers (where each commands in between must honor a flag). To be honest, I have not used commons-chain yet, this is just an analysis from what I understand so far. The potential problems here is about the index-based binding in the Chain interface. The Chain interface bind commands based on the order the commands are added. So we can not jump to a logically named command in a chain. This makes the index-based jump the only possible way.
This is not a case of Command looking for flags, but a case of the Command examining the state of the Context and deciding whether the current Context applies to them or not. It is perfectly normal and expected for many Command to be called but to do nothing (and return false). Jumping is not something you need to do externally.
In fact, I would say that avoiding jumps is why we have the Chain of Responsibility in the first place. We don't want to work that hard. We want to hand the Context to the Command (or Chain of Commands), and let the Commands do what they will.
For more on the intent of the CoR, see the Design Patterns book.
It's possible that you are not imagining the Chains to finely enough grained. An application can use as many Chains (or Catalogs) as needed. A service method (like a Struts Action) can determine which Chain to call from which Catalog under which circumstances. The need for a "jump behavior" might imply that the Chain is too coarsely grained and needs to be refactored.
If this thread were based on an actual use-case with a real Chain and real Commands, then we could look at alternative ways to implement the Chain. But since it isn't, we can't.
* If in the end, the fundamental APIs do not want to deal with "jump behavior", I still could not successfully implement an extended Chain to make up the capability. From the original publication about the Chain of Responsibility, it does not dictate "jump behavior" is prohibited or "branch behavior" is only allowed. In my world view, the three behaviors are equally important: "sequence behavior", "branch behavior", and "jump behavior" in an extreme configurable chain.
IMHO, these behaviors out of scope for an implementation of the Chain of Responsibility pattern. Many implementations don't even return false or have the Filter backdoor. These are optimizations Craig made to help with resource-intensive operations. In many implementations, every Command on the Chain is visited, and there may not even be a guarantee that any of the Commands handles the request. I don't see "jump behavior" as an essential part of the CoR "world view". The boolean/Filter behavior is a stretch as it is, and it is probably as far we can go and still call it a GoF CoR.
* There are more issues. But I get to stop here for a clear view of my thinking. Again, this is derived from what I estimated from the codes. If any thing incorrect or there is already a solution to the problem, I'd be interested. At least, I have more understanding to commons-chain now :-)
The best solution would be to roll up your sleeves and start using the CoR in your own implementations. The pattern is very well known and well documented. The Gang of Four has already done the whiteboard for us. We are past the point of "armchair engineering". IMHO, any changes to the API should be based on concrete needs and live use-cases, rather than speculation.
As I believe Craig mentioned, this is open source. If you think Chain should be extended in a certain way, then go ahead extend it, and let us know how it turns out.
-Ted.
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
