观察者模式定义:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式有四个角色:
抽象通知者角色(Subject):定义了通知的接口规则。
具体通知者角色(ConcreteSubject):实现抽象通知者的接口,接到状态改变向观察者下发通知。
抽象观察者角色(Observer):定义接到通知后所做的操作接口规则。
具体观察者角色(JingDong):实现具体操作方法。
考虑这样一种场景,有个电商平台,每天都要统计客户数据和订单数据,那么就可以定义一个类(Subject),当每天时间发生变化时,就要通知更新客户数据(Observer)和订单数据(Observer)。
本代码基于Yii2.0 具体通知者类: <?php namespace common\services; use Yii; use SplObserver; class SubjectService implements \SplSubject { protected $observers; public function __construct() { $this->observers = new \SplObjectStorage(); } /** * 获取参数 * @return mixed */ public function getParams() { return $this->observers->getInfo(); } /** * 添加观察者 * @param SplObserver $observer * @param null $params */ public function attach(SplObserver $observer,$params = null) { $this->observers->attach($observer,$params); } /** * 移除观察者 * @param SplObserver $observer */ public function detach(SplObserver $observer) { $this->observers->detach($observer); } /** * 通知观察者 */ public function notify() { foreach ($this->observers as $obj) { try { $obj->update($this); } catch (\Throwable $e) { } } } }
具体观察者类:
<?php namespace common\services; use Yii; use SplSubject; use common\services\SubjectService;
/** * 客户统计类 * Class UserObserverService * * @package common\services */ class UserObserverService implements \SplObserver { /** *更新数据 * @param SplSubject $subject */ public function update(SplSubject $subject) { //获取参数 $params = $subject->getParams(); //统计数据 $this->statData($params); } /** *统计客户数据 * @param $params */ public function statData($params) { echo "stat user data"; } }
<?php namespace common\services; use Yii; use SplSubject; use common\services\SubjectService; /** * 订单统计类 * Class OrderObserverService * * @package common\services */ class OrderObserverService implements \SplObserver { /** *更新数据 * @param SplSubject $subject */ public function update(SplSubject $subject) { //获取参数 $params = $subject->getParams(); //统计数据 $this->statData($params); } /** *统计订单数据 * @param $params */ public function statData($params) { echo "stat order data"; } } 测试类:
<?php namespace backend\controllers; use common\services\SubjectService; use common\services\UserObserverService; use common\services\OrderObserverService; use Yii; use yii\web\Controller; class ObserverTestController extends Controller { /** * 测试 */ public function actionIndex() { $day = date('Y-m-d'); $subject = \Yii::createObject(SubjectService::class); $subject->attach(new UserObserverService(),['day'=>$day]); $subject->attach(new OrderObserverService(),['day'=>$day]); $subject->notify(); } }