當一個對象狀態發生改變後,會影響到其他幾個對象的改變,這時候可以用觀察者模式。像wordpress這樣的應用程序中,它容外部開發組開發插件,比如用戶授權的博客統計插件、積分插件,這時候可以應用觀察者模式,先註冊這些插件,當用戶發佈一篇博文後,就回自動通知相應的插件更新。
觀察者模式符合接口隔離原則,實現了對象之間的鬆散耦合。
觀察者模式UML圖:
在php SPL中已經提供SplSubject和SqlOberver接口
interface SplSubject
{
function attach(SplObserver $observer);
function detach(SplObserver $observer);
function notify();
}
interface SqlObserver
{
function update(SplSubject $subject);
}
class Subject implements SplSubject
{
private $observers;
public function attach(SplObserver $observer)
{
if (!in_array($observer, $this->observers)) {
$this->observers[] = $observer;
}
}
public function detach(SplObserver $observer)
{
if (false != ($index = array_search($observer, $this->observers))) {
unset($this->observers[$index]);
}
}
public function post()
{
//post相關code
$this->notify();
}
private function notify()
{
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
public function setCount($count)
{
echo "數據量加" . $count;
}
public function setIntegral($integral)
{
echo "積分量加" . $integral;
}
}
class Observer1 implements SplObserver
{
public function update($subject)
{
$subject-> setCount(1);
}
}
class Observer2 implements SplObserver
{
public function update($subject)
{
$subject-> setIntegral(10);
}
}
class Client
{
public function test()
{
$subject = new Subject();
$subject->attach(new Observer1());
$subject->attach(new Observer2());
$subject->post();//輸出:數據量加1 積分量加10
}
}