第5课:设计模式之命令链模式

命令链模式以松散耦合主题为基础,发送消息、命令和请求,或通过一组处理程序发送任意内容。每个处理程序都会自行判断自己能否处理请求。如果可以,该请求被处理,进程停止。您可以为系统添加或移除处理程序,而不影响其他处理程序。

是不是感觉和观察者模式有相似的地方?都有触发,都有命令,那么他们的区别在哪里呢?
用一个例子来说明
比如说在上课的时候你玩手机游戏,比较二的是你没关声音,老师火了,找班主任说了情况,班主任也管不了,然后告状到你父母,于是你的魔鬼日子来临了,这是命令链模式,老师、班主任、父母都是链中的一个具体角色,事件在链中传递,最终由一个具体的节点来处理,并反馈结果给调用者。那观察者模式是怎么样的?你还是在课堂上玩游戏,老师火了,但是老师没有想告状,而是掏出个扩音器来讲课,于是你玩游戏的声音打扰不到其他人了,但是其他同学作为观察者都要听喇叭了,这就是触发链,其中老师既是观察者(相对你)也是被观察者(相对其他同学)

用代码举例说明命令链模式:
<?php
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{
  public function onCommand( $name, $args )
  {
    if ($name != 'user') return false;
    echo( "UserCommand handling 'user'\n" );
    return true;
  }
}

class GodeyeCommand
{
    public function onCommand($name, $args) {
        if ($name != 'godeye') return false;
        echo( "www.godeye.org\n" );
        return true;
    }
}

$cc = new CommandChain();
$cc->addCommand(new UserCommand());
$cc->addCommand(new MailCommand());
$cc->runCommand('user', null);
$cc->runCommand('godeye', null);
代码是不是和观察者也有点像?但是你仔细理解,发现他们的原理很不同
addCommand是把相关的类加入的命令链条,让他们产生关联
runCommand是调用命令,至于谁来执行
foreach($this->_commands as $cmd) {
  if ($cmd->onCommand($name, $args))
      return;
}
是通过这个循环来做的,如果onCommand返回真,证明这个任务被人接收并处理了,直接返回,不再继续下去
而观察者不同,他以广播的形式通知所有的观察者,执行他们约定的方法