观察者模式当对象间存在一对多关系时,则使用观察者模式。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
在php中,SplObserver接口与SplSubject一起使用以实现观察者设计模式。
例:如一个用户上线后,通知他的好友并给他推送消息
<?php
//观察者1号,好友
class Friends implements SplObserver {
//接收被观者的更新通知
public function update(SplSubject $subject) {
echo "你的好友".$subject->name."上线了!";
}
}
//观察者二号
class PushMsg implements SplObserver {
public function update(SplSubject $subject) {
echo "hello,",$subject->name;
}
}
//被观察者,用户
class User implements SplSubject {
private $_observers;
public $name;
public function __construct($name) {
//SplObjectStorage类提供了从对象到数据的映射,或者通过忽略数据,提供了一个对象集
$this->_observers = new SplObjectStorage();
$this->name = $name;
}
//新来一个观察者
public function attach(SplObserver $observer) {
$this->_observers->attach($observer);
}
//离开了一个观察者
public function detach(SplObserver $observer) {
$this->_observers->detach($observer);
}
//通知观察者
public function notify() {
foreach ($this->_observers as $observer) {
$observer->update($this);
}
}
public function login() {
$this->notify();
}
}
$observer1= new Friends();
$observer2=new PushMsg();
$user=new User('小明');
$user->attach($observer1);
$user->attach($observer2);
$user->login();