A Composite Command Chain

Posted by John Kleijn • Tuesday, May 27. 2008 • Category: PHP

My idea of fun is to combine existing patterns, producing a solution to more specialized problem than the original pattern specifications individually. I should probably get out more.

In this case, I was faced with the following problem: how to create a flexible, complex and multi-dimensional chain of Command Objects (a chain of commands and subcommands), that was executable top down over and over, without re-executing the same command twice for that chain. Operations should block the execution of their children on failure to complete. Children should be executed serial, and isolated from each others potential failure.

When faced with creating complex relations between objects of the same type, with operations to be executed on the underlying structure transparently, the Composite pattern can usually save the day. I created a mechanism to create a composite structure of any implementation of an abstract Command Object class.

Because I implemented Composite, I already had a mechanism to execute a Command and it's descendants in the order required.



/**
* Execute this Command and it's children
*
* @param array $args Override for construction arguments
*
* @throws System_Command_Exception
*
* @return unknown
*/

final public function execute(array $args = null)
{
        $this->_doExecute($args);
        $this->executeChildCommands($args);
}
 

Method executeChildCommands() simply invokes execute() on all children of this Command, which will ensure every child's children are executed, etc. I placed the invocation of execute() in executeChildCommands() in a try block, to ensure all of a Commands' children we're always executed. Serial and isolated execution for child Commands was a fact.

Of course, the above implementation only has the desired behaviour if there is explicit failure. This is not what I really want, perhaps a Command is simply still 'pending'. Also, there is no mechanism yet to prevent multiple successful execution of the same command.

Enabling this property of the chain is simple. Every Command gets a 'completed' flag, skipping execution of Commands that test positive against this flag, and preventing execution of the children of a Command that tests negative. Every command will have evaluate if the local command is completed or not, and set the property accordingly.


final public function execute(array $args = null)
{
        if(!$this->isCompleted())
        {
                $this->_doExecute($args);
        }
        if($this->isCompleted())
        {
                $this->executeChildCommands($args);
        }
}
 

Now I can re-execute the chain from it's root as many times as like, until all Commands have completed, if ever.

There is some resemblance to the Chain of Responsibility pattern. In a Chain of Responsibility, the request is forwarded down a (simple) chain, until an object in the chain can satisfy the request. I'm doing the opposite. The request is processed until an object cannot satisfy the request. Like the Chain of Responsibility, the exact handler (handlers in this case) is implicit. Since my intent is exactly opposite to the Chain of Responsibility, one could label it 'negative' Chain of Responsibly. Or even Composite Negative Chain of Command. But only if you're really fond of labeling. Or if the contents of your refrigerator is sorted alphabetically.

0 Trackbacks

  1. No Trackbacks

0 Comments

Display comments as (Linear | Threaded)
  1. No comments

Add Comment

You can use [geshi lang=lang_name [,ln={y|n}]][/geshi] tags to embed source code snippets.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA


Antiquities and such