定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
最近因为工作变动的原因,很久没有更新博客了,这两天终于缓下来,继续完成我的设计模式篇。
今天要讨论的是,观察者模式,这是一个很容易理解的模式,不过大道至简,如独狐九剑,一刺一挑在对方的弱点上,往往能发挥最强的威力…高手飞花拈叶匀能伤人…老人挤公交往往是一把好手…(举个例子,插件机制用此模式浑然天成)。
以上纯属废(hui)话,接下来进入正题:
先看UML:
《img 占位 哥还没找到好看的UML工具》
我看来看下原生态的代码:
<?php
interface Subject {
public function attach(Observer $observer);
public function detach(Observer $observer);
public function notify();
}
interface Observer {
public function update(Subject $subject);
}
class DemoSubject implements Subject {
private $observers;
public function __construct() {
$this->observers = array();
}
public function attach(Observer $observer) {
$this->observers[] = $observer;
}
public function detach(Observer $observer) {
if($idx = array_search($observer, $this->observers, true)) {
unset($this->observers[$idx]);
}
}
public function notify() {
foreach($this->observers as $observer) {
$observer->update($this);
}
}
}
class DemoObserver implements Observer {
public function update(Subject $subject){
//doSometing;
//echo 'update!';
}
}
我们把echo ‘update’;这个注释去掉测试一下
$subject = new DemoSubject();
$observer = new DemoObserver();
$subject->attach($observer);
$subject->notify();
更具威力的是当你有DemoObserver1,DemoObserver2…DemoObserverN时,只要你注册到Subject中,都能在notify时候被通知道,并且代码具有最小藕合与扩展的灵活性;
————————我是蛋疼的分割线————————
刚刚我们讲到的是我们手动实现的两个接口类,其实PHP5中已经有内置的主题/观察者接口,他的原型如下:
<?php
//http://cn.php.net/manual/en/class.splsubject.php
interface SplSubject {
public function attach(SplObserver $observer);
public function detach(SplObserver $observer);
public function notify();
}
//http://cn.php.net/manual/en/class.splobserver.php
interface SplObserver {
public function update(SplSubject $subject);
}
于是我们可以不用自己去写接口,而是直接使用内置接口:
<?php
class DemoSubject implements SplSubject {
private $observers;
public function __construct() {
$this->observers = array();
}
public function attach(SplObserver $observer) {
$this->observers[] = $observer;
}
public function detach(SplObserver $observer) {
if($idx = array_search($observer, $this->observers, true)) {
unset($this->observers[$idx]);
}
}
public function notify() {
foreach($this->observers as $observer) {
$observer->update($this);
}
}
}
class DemoObserver implements SplObserver {
public function update(SplSubject $subject){
//doSometing;
//echo 'update!';
}
}
纸上得来终觉浅,绝知此事要躬行。等把这一系列文章写完后,会写几篇文章描述在实际编码中如何去使用此模式。