文章目录 [+]
什么是观察者模式
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
场景
当一个事件发生后,要执行一连串更新操作,传统的编程方式,就是在事件的代码之后直接加入处理逻辑,当更新逻辑增多之后,代码变得难以维护,这种方式是耦合式的,侵入式的,增加新的逻辑需要改变事件主题的代码。
观察者模式实现了低耦合,非侵入式的通知与更新。
观察者模式主要角色
抽象主题(Subject)角色:主题角色将所有对观察者对象的引用保存在一个集合中,每个主题可以有多个观察者。抽象主题提供了增加和删除观察者对象的接口。
抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在观察的主题发生改变时更新自己。
具体主题(ConcreteSubject)角色:存储相关状态到具体观察者对象,当具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。
具体观察者(ConcretedObserver)角色:存储一个具体主题对象,存储相关状态,实现抽象观察者角色所要求的更新接口,以使得其自身状态和主题的状态保持一致。
观察者模式的优点和确定
观察者模式的优点:
观察者和主题之间的耦合度较小;
支持广播通信。
观察者模式的缺点:
由于观察者并不知道其他观察者的存在,它可能对改变目标的最终代价一无所知。这可能会引起意外的更新。
简单代码实例
<?php /** * Created by PhpStorm. * User: 猫巷 * Email:catlane@foxmail.com * Date: 18-7-26 * Time: 上午10:12 */ /** * 观察者模式 */ /** * 抽象主题角色 * Interface Subject */ interface Subject { /** * 增加一个新的观察者对象 * @param Observer $observer * @return mixed */ public function attach ( Observer $observer ); /** * 删除一个已存在的观察者对象 * @param Observer $observer * @return mixed */ public function detach ( Observer $observer ); /** * 通知所有注册过的观察者模式 * @return mixed */ public function notifyObservers (); } /** * 抽象观察者角色 * Interface Observer */ interface Observer { /** * 更新方法 * @return mixed */ public function update (); } /** * 具体主题角色 * Class ConcreteSubject */ class ConcreteSubject implements Subject { private $_observers; public function __construct () { $this->_observers = []; } /** * 增加一个新的观察者对象 * @param Observer $observer * @return mixed */ public function attach ( Observer $observer ) { // TODO: Implement attach() method. return array_push ( $this->_observers , $observer ); } /** * 删除一个已存在的观察者对象 * @param Observer $observer * @return mixed */ public function detach ( Observer $observer ) { // TODO: Implement detach() method. $index = array_search ( $observer , $this->_observers ); if ( $index === FALSE || ! array_key_exists ( $index , $this->_observers ) ) { return FALSE; } unset( $this->_observers[ $index ] ); return TRUE; } /** * 通知所有注册过的观察者模式 * @return mixed */ public function notifyObservers () { // TODO: Implement notifyObservers() method. if ( ! is_array ( $this->_observers ) ) { return FALSE; } foreach ( $this->_observers as $ovserver ) { $ovserver->update (); } return TRUE; } } /** * 具体观察者角色 * Class ConcreteObserver */ class ConcreteObserver implements Observer { private $_name; public function __construct ( $name ) { $this->_name = $name; } /** * 更新方法 * @return mixed */ public function update () { echo 'Observer' , $this->_name , "has notifed\r\n"; } } //实例化类 $subject = new ConcreteSubject(); //添加第一个观察者 $observer1 = new ConcreteObserver( 'Martin' ); $subject->attach ( $observer1 ); echo '<br /> 第一次通知:<br />'; $subject->notifyObservers(); $observer2 = new ConcreteObserver( 'phppan' ); $subject->attach ( $observer2 ); echo '<br /> 第二次通知:<br />'; $subject->notifyObservers(); $subject->detach ( $observer1 ); echo '<br /> 第一次通知:<br />'; $subject->notifyObservers();
Laravel中实现
在Laravel中,我们可以用事件来实现这个功能,下篇文章就来具体通过Laravel的项目进行详细的讲解。
发表评论