// 抽象的观察者类,规定要有一个update方法
abstract class AbstractObserver {
abstract function update(AbstractSubject $subject_in);
}
// 抽象的主题类
abstract class AbstractSubject {
abstract function attach(AbstractObserver $observer_in);
abstract function detach(AbstractObserver $observer_in);
abstract function notify();
}
function writeln($line_in) {
echo $line_in.PHP_EOL;
}
// 观察者类的子类
class FruitbuyerObserver extends AbstractObserver {
public function __construct() {
}
public function update(AbstractSubject $subject) {
writeln('新的最喜爱的水果是: '.$subject->getFavorites());
}
}
// 主题类的子类
class FruitbuyerSubject extends AbstractSubject {
private $favoritePatterns = NULL;
private $observers = array();
function __construct() {
}
function attach(AbstractObserver $observer_in) {
$this->observers[] = $observer_in;
}
function detach(AbstractObserver $observer_in) {
foreach($this->observers as $okey => $oval) {
if ($oval == $observer_in) {
unset($this->observers[$okey]);
}
}
}
function notify() {
foreach($this->observers as $obs) {
$obs->update($this);
}
}
function updateFavorites($newFavorites) {
$this->favorites = $newFavorites;
$this->notify();
}
function getFavorites() {
return $this->favorites;
}
}
writeln('开始测试观察者模式');
writeln('');
$fruitbuyer = new FruitbuyerSubject();
$fruitbuyerObserver = new FruitbuyerObserver();
// 把一个观察者放进$fruitbuyer的已知观察者名单中,现在$fruitbuyer有了一个观察者对象
$fruitbuyer->attach($fruitbuyerObserver );
// 这步是关键,先把“苹果”加入水果买家的最爱列表
// 接着该updateFavorites()操作会调用已注册的(目前只有一个)所有观察者自身的update()方法
// 就是说告知(notify)所有的观察者们,让他们都知道$fruitbuyer最喜欢的水果是“苹果”
$fruitbuyer->updateFavorites('苹果');
// 现在换成了西瓜,$fuitbuyer一旦更改了喜好,同时会告知所有的观察者们,现在观察者们也知道了新的喜好是“西瓜”
$fruitbuyer->updateFavorites('西瓜');
// 去掉一个观察者
$fruitbuyer->detach($fruitbuyerObserver );
// 现在因为没有了观察者,所以$fruitbuyer更新了喜好为黄瓜,但是能通知谁呢?没人知道他喜欢的是“黄瓜”了哦~~~
$fruitbuyer->updateFavorites('黄瓜');
writeln('');
writeln('结束测试观察者模式');
开始测试观察者模式
新的最喜爱的水果是: 苹果
新的最喜爱的水果是: 西瓜
结束测试观察者模式