概念: 观察者模式有时也被称作发布/订阅模式,该模式用于为对象实现发布/订阅功能:一旦主体对象状态发生改变,与之关联的观察者对象会收到通知,并进行相应操作。
思路:将所有观察者注册到被观察者的列表中,当被观察者接收到消息之后,循环调用列表通知给每个观察者。
角色:观察者、主体注册中心、实现主体并广播给所有观察者
观察者例子:猫吃鱼类,狗吃骨头类
实现主体接口,主要就是添加观察者和广播通知观察者
两个类向主体注册中心注册,添加到数组中,
实现者通过调用主体数组并循环出调用吃的动作,从而实现广播的作用
例:有人将猫,狗这两个类对象告诉我(分别调用add添加方法),我记住(保存到数组找中),然后他在告诉我该他们到点该吃了,我在逐个通知狗和猫去吃(调用通知方法,循环两个类调用eat方法)
<?php
/**
* 被观察者接口类
*/
interface Observerable
{
//注册观察者
public function registerObserver(Observer $o);
//移除观察者
public function removeObserver(Observer $o);
//通知观察者
public function notifyObserver();
}
/**
* 被观察者类:实现操作观察者的方法
*/
class SimpleHeroGame implements Observerable
{
private $message;
private $list = [];
// public function __construct(){
// }
//注册所有观察者
public function registerObserver(Observer $ob){
array_push($this->list, $ob);
}
//移除观察者
public function removeObserver(Observer $ob){
$key = array_search($ob, $this->list);
array_splice($this->list, $key, 1);
}
//发送消息给观察者
public function notifyObserver(){
$count = count($this->list);
for ($i=0; $i < $count; $i++) {
$this->list[$i]->update($this->message);
}
}
//设置系统消息,并发送给观察者
public function setInfomation($messsage){
$this->message = $messsage;
echo '系统发出消息:' . $messsage . '<br>';
$this->notifyObserver();
}
}
//观察者接口类
interface Observer
{
public function update($message);
}
/**
* 观察者实例
*/
class Hero implements Observer
{
private $name;
private $message;
function __construct($heroName)
{
$this->name = $heroName;
}
public function update($message){
$this->message = $message;
$this->read();
}
public function read(){
echo $this->name .'接收消息:'. $this->message . '<br>';
}
}
//=======================================================================================
//观察者模式测试
//
class ObserverTest
{
public static function main(){
$heroGlory = new SimpleHeroGame();
$hanXin = new Hero('韩信');
$caiWenJi = new Hero('蔡文姬');
$houYi = new Hero('后裔');
$daJi = new Hero('妲己');
$liuShan = new Hero('刘禅');
$heroGlory->registerObserver($hanXin);
$heroGlory->registerObserver($caiWenJi);
$heroGlory->registerObserver($houYi);
$heroGlory->registerObserver($daJi);
$heroGlory->registerObserver($liuShan);
$heroGlory->setInfomation('敌军还有5秒到达战场,请做好准备!');
$heroGlory->setInfomation('double kill');
}
}
require 'observer.php';
ObserverTest::main();