漫谈设计模式之观察者模式

1468149247

观察者模式定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。

打个比方,就拿梦幻西游战斗中轮流出招来说,三个人物,龙太子,剑侠客,逍遥生,先是龙太子出招,他先作为事件的发生者,然后其他两个人物作为观察者剑侠客,逍遥生的游戏界面就会更新着画面显示龙太子出招。

观察者接口实现

<?php
/**

  • Created by PhpStorm.
  • User: Ape
  • Date: 2016-7-10
  • Time: 14:39
  • /

namespace Open\Observer;

/**

  • 所有观察者必需实现此接口

  • Interface Observer

  • @package Open\Observer

  • /
    interface Observer
    {
    /**

    • 观察者更新方法

    • @param null $msg

    • @return mixed

    • /
      function update($msg = null);
      }

      事件源基类的实现

<?php
/**

  • Created by PhpStorm.
  • User: Ape
  • Date: 2016-7-10
  • Time: 14:51
  • /

namespace Open\Observer;

abstract class Event
{
/**
* 这里设置为private,事件发生者不用关心
* @var array
*/
private $observers = array();

/**
 * 添加观察者
 * @param Observer $observer
 */
function addObserver(Observer $observer){
    $this->observers[] = $observer;
}

/**
 * 移除观察者
 * @param Observer $observer
 */
function removeObserver(Observer $observer){
    foreach($this->observers as $k => $value)
        if($observer === $value)
            unset($this->observers[$k]);
}

/**
 * 通知所有观察者更新
 * @param null $msg
 */
function notify($msg = null){
    foreach($this->observers as $observer)
        $observer->update($msg);
}

}

龙太子

<?php
/**

  • Created by PhpStorm.
  • User: Ape
  • Date: 2016-7-10
  • Time: 15:07
  • /

namespace Open\Observer;

class Event1 extends Event implements Observer
{
public $name = ‘龙太子’;

public function trigger(){
    $m = $this->name.':我使出龙腾<br/>';
    echo $m;
    $this->notify($this->name.'使出龙腾<br/>');
}

public function update($msg = null){
    echo $this->name.'看到'.$msg.'<br/>';
}

}

剑侠客

<?php
/**

  • Created by PhpStorm.
  • User: Ape
  • Date: 2016-7-10
  • Time: 15:07
  • /

namespace Open\Observer;

class Event2 extends Event implements Observer
{
public $name = ‘剑侠客’;

public function trigger(){
    $m = $this->name.':我使出横扫千军<br/>';
    echo $m;
    $this->notify($this->name.'使出横扫千军<br/>');
}

public function update($msg = null){
    echo $this->name.'看到'.$msg.'<br/>';
}

}

逍遥生

<?php
/**

  • Created by PhpStorm.
  • User: Ape
  • Date: 2016-7-10
  • Time: 15:07
  • /

namespace Open\Observer;

class Event3 extends Event implements Observer
{
public $name = ‘逍遥生’;

public function trigger(){
    $m = $this->name.':我使出牛刀小试<br/>';
    echo $m;
    $this->notify($this->name.'使出牛刀小试<br/>');
}

public function update($msg = null){
    echo $this->name.'看到'.$msg.'<br/>';
}

}

注:以上三个类既作为事件发生者也作为观察者
测试代码

<?php
$event1 = new Open\Observer\Event1();
$event2 = new Open\Observer\Event2();
$event3 = new Open\Observer\Event3();

$event1->addObserver($event2);
$event1->addObserver($event3);
echo “现在是 $event1->name 出招
“;
$event1->trigger();

$event2->addObserver($event1);
$event2->addObserver($event3);
echo “现在是 $event2->name 出招
“;
$event2->trigger();

$event3->addObserver($event1);
$event3->addObserver($event2);
echo “现在是 $event3->name 出招
“;
$event3->trigger();

结果输出

现在是 龙太子 出招
龙太子:我使出龙腾
剑侠客看到龙太子使出龙腾
逍遥生看到龙太子使出龙腾

现在是 剑侠客 出招
剑侠客:我使出横扫千军
龙太子看到剑侠客使出横扫千军
逍遥生看到剑侠客使出横扫千军

现在是 逍遥生 出招
逍遥生:我使出牛刀小试
龙太子看到逍遥生使出牛刀小试
剑侠客看到逍遥生使出牛刀小试