php的观察者模式
1、观察者模式是一种非常简单得事件系统,包含了两个或更多的互相交互的类。这一模式允许某个类观察两一个类的状态,当被观察类的状态发生变化时,这个模式会得到通知。
在观察者模式中,被观察的类叫做subject,而负责观察的类叫做observer.为了表达这些内容,SPL提供了SplSubject和SplObserver接口。
SplSubject接口
Interface SplSubject{
Public function attach(SplObserver $observer);
Public function detach(SplObserver $observer);
Public function notify();
}
Interface SqlObserver{
Public function update(SqlSubject $subject);
}
2、这一模式的概念是SplSubject类维护了一个特定状态,当这个状态发生变化时,它就会调用notify()方法,调用notify()方法时,所有值钱使用attach()方法注册的SqlObserver实例的update()方法都会被调用。
Observer模式
Class DemoSubject implements SqlSubject{
Private $observers,$value;
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);
}
}
Public function setValue($value){
$this->value=$value;
$this->notify();
}
Public function getValue(){
return $this->value;
}
}
Class DemoObserver implements SplObserver{
Public function update(SplSubject $subject){
Echo ‘The new value is’.$subject->getValue();
}
}
$subject = new DemoSubject();
$observer = new DemoObserver();
$subject->attach($observer);
$subject->setValue(5);
3、观察者模式的优点在于挂接到订阅者上的观察者可多可少,并且不需要提前知道那个类会响应subject类发生的事件。
Php6提供了SplObjectStorage类,这个类提升了观察者模式的可用性。这个类与数组相似。但它只能存储具有唯一性的对象,而且只存储这些对象的引用。这种做法有几个好处。首先,不能挂接一个类两次,也正因为如此,可以防止多次调用同一个对象的update()方法。而且,不需要迭代访问或者搜集集合,就可以从集合中删除某个对象,这提高了运行效率。
由于SplObjectStorage支持Iterator接口,所以可以将它用在foreach循环中,就像是用一个普通数组一样。
4、SplObjectStorage和观察者模式
Class DemoSubject implements SplSubject{
Private $observers,$value;
Public function __construct(){
$this->observers = new SplObjectStorage();
}
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 setValue($value){
$this->value=$value;
$this->notify();
}
Public function getValue(){
return $this->value;
}
Class DemoObserver implemnts SplObserver{
Public function update(SplObject $subject){
Echo ‘The new value is ’.$subject->getValue();
}
}
$subject =new DemoSubject();
$observer =new DemoObserver();
$subject->attach($observer);
$subject->setValue(5);
}