Saturday, May 23, 2009

The chain-of-command pattern using PHP

Building on the loose-coupling theme, the chain-of-command pattern routes a message, command, request, or whatever you like through a set of handlers. Each handler decides for itself whether it can handle the request. If it can, the request is handled, and the process stops. You can add or remove handlers from the system without influencing other handlers. Chain.php shows an example of this pattern.

Chain.php

<?php
interface ICommand {
function onCommand($name, $args);
}

class CommandChain {
private $_commands = array();

public function addCommand($cmd) {
$this->_commands []= $cmd;
}

public function runCommand($name, $args) {
foreach($this->_commands as $cmd) {
if ($cmd->onCommand($name, $args))
return;
}
}
}

class UserCommand implements ICommand {
public function onCommand($name, $args) {
if ($name != 'addUser') return false;
echo( "UserCommand handling 'addUser'\n" );
return true;
}
}

class MailCommand implements ICommand {
public function onCommand($name, $args) {
if ($name != 'mail') return false;
echo( "MailCommand handling 'mail'\n" );
return true;
}
}

$cc = new CommandChain();
$cc->addCommand( new UserCommand() );
$cc->addCommand( new MailCommand() );
$cc->runCommand( 'addUser', null );
$cc->runCommand( 'mail', null );
?>


This code defines a CommandChain class that maintains a list of ICommand objects. Two classes implement the ICommand interface -- one that responds to requests for mail and another that responds to adding users. The UML is shown in the figure.

The command chain and its related commands
The command chain and its related commands


If you run the script, which contains some test code, you see the following output:


% php chain.php
UserCommand handling 'addUser'
MailCommand handling 'mail'
%


The code first creates a CommandChain object and adds instances of the two command objects to it. It then runs two commands to see who responds to those commands. If the name of the command matches either UserCommand or MailCommand, the code falls through and nothing happens.
The chain-of-command pattern can be valuable in creating an extensible architecture for processing requests, which can be applied to many problems.
source: ibm.com

Design Patterns for PHP

No comments:

Post a Comment