<?php
/**
* @来自 http://www.php.net/manual/en/class.splobserver.php
* 报纸
* 观察者模式中的主体
* 使用了spl中的观察者模式的接口,so php>=5.3
* 整理: 苏小林
*/
class Newspaper implements \SplSubject{
private $name;
private $observers = array();
private $content;
public function __construct($name) {
$this->name = $name;
}
//添加一个观察者
public function attach(\SplObserver $observer) {
$this->observers[] = $observer;
}
//删除一个观察者
public function detach(\SplObserver $observer) {
//获取待删除的观察者所在的键
$key = array_search($observer,$this->observers, true);
if($key){
//删除指定观察者
unset($this->observers[$key]);
}
}
//发生了突发新闻
public function breakOutNews($content) {
$this->content = $content;
//通知观察者,调用主体的notify方法
$this->notify();
}
public function getContent() {
return $this->content." ({$this->name})";
}
//通知所有观察者(或者可以选择性的通知某些观察者)
public function notify() {
foreach ($this->observers as $value) {
$value->update($this);
}
}
}
/**
* 收到主体通知的观察者
*/
class Reader implements SplObserver{
private $name;
public function __construct($name) {
$this->name = $name;
}
//收到新闻后的动作,参数为主体对象
public function update(\SplSubject $subject) {
echo $this->name." is reading breakout news <b>".$subject->getContent()."</b>\n";
}
}
//主体(报纸)
$newspaper = new Newspaper("Newyork Times");
$allen = new Reader("Allen");
$jim = new Reader("Jim");
$linda = new Reader("Linda");
//保存添加观察者到主体中(读者)
$newspaper->attach($allen);
$newspaper->attach($jim);
$newspaper->attach($linda);
//从主体中删除指定的观察者
$newspaper->detach($linda);
//发布一个突发新闻(触发观察者的行为)
$newspaper->breakOutNews("USA break down!");
//=====输出======
//Allen is reading breakout news USA break down! (Newyork Times)
//Jim is reading breakout news USA break down! (Newyork Times)