觀察者模式可以粗略的理解為,一個類(我們稱之為被觀察者,就是下文中的boss),這個類繼承了一個被觀察者容器的接口, 該接口中的方法有:添加觀察者,踢出觀察者,提醒觀察者,和觸發條件(或者叫觀察條件,滿足該條件時,就通知觀察者) 。
添加觀察者即相當於把一些類注冊到這個容器之中,當然這些類的前提是需要有一個相應被觀察者反應信息的方法, 被觀察者容器通過接受不同的觀察條件參數來判斷是否需要提醒所有本容器中的已經注冊過的觀察者。一旦滿足提醒條件,提醒容器內所有觀察者讓其調用相應方法並且實現對應觀察者實例的變化。
以本文使用的實例為例,小販要觀察的是城管,就是說城管就是被觀察者(boss類),有2個小販,說明2個小販需要留意城管是否出現,如果觀察到城管出現了,就要跑。新來了一個小販,也要增加到觀察者容器裡,增加了這個小販之後,一共有3個小販需要留意城管是否出現。如果在城管出現(就是觸發條件沒滿足)之前,小販走了,就是踢出觀察者操作。
下邊是實例代碼:
<?php
header(“Content-type:text/html;charset=utf-8″);
interface iWatcher {
public function attach($observer); //增加觀察者
public function dettach($observer);//踢出觀察者
public function subjectState($subject);//滿足條件
public function notify();//滿足條件時通知觀察者
}
class boss implements iWatcher{
public $_action;//觸發條件
private $_observer;//觀察者
public function attach($observer){//增加一個觀察者
$this->_observer[] = $observer;
}
public function dettach($observer){//踢出一個觀察者
$object_key = array_search($observer,$this->_observer);
if($object_key !== false){
unset($this->_observer[$object_key]);
}else{
exit(“不存在此觀察者”);
}
}
public function notify(){//通知觀察者
foreach($this->_observer as $server){
$server->update();
}
}
public function subjectState($subject){//觸發條件
$this->_action = $subject;
}
}
abstract class observer{
protected $user_name;
protected $subject;
public function __construct($user_name,$subject){
$this->user_name = $user_name;
$this->subject = $subject;
}
public abstract function update();
}
class stockObserver extends observer{
public function __construct($user_name,$subject){
parent::__construct($user_name,$subject);
}
public function update(){
echo $this->subject->_action.$this->user_name.”你快跑!”;
}
}
$huhansan = new boss();//被觀察者
$sanmao = new stockObserver(“小販”,$huhansan);//初始化觀察者
$huhansan->attach($sanmao);//增加一個觀察則
$huhansan->attach($sanmao);//再增加一個觀察者
$huhansan->dettach($sanmao);//踢出一個觀察者
$huhansan->subjectState(“城管來了!”);//滿足的觸發條件
$huhansan->notify();//通知觀察者
?>