博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP设计模式-观察者模式
阅读量:5875 次
发布时间:2019-06-19

本文共 3145 字,大约阅读时间需要 10 分钟。

观察者模式(又称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它是将行为独立模块化,降低了行为和主体的耦合性。它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

  • Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。

  • ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。

  • Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。

  • ConcrereObserver:具体观察者,是实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

PHP 内置了

  • SplSubject 抽象主题 Interface

  • SplObserver 抽象观察者 Interface

接口约束

// 主题 被观察者interface SplSubject {    public function attach(SplObserver $observer); //注册观察者到当前主题    public function detach(SplObserver $observer); //从当前主题删除观察者    public function notify(); //主题状态更新时通知所有的观察者做相应的处理}// 观察者interface SplObserver {    public function update(SplSubject $subject); //注册观察者到当前主题}

通过项目中的实际应用能更容易的去理解观察者模式

下面我们以用户为主题,邮件模块和短信模块为观察者

当用户注册成功时,邮件观察者或短信观察者则收到相应的通知,发送邮件和短信给用户

User 主题

name = $name; $this->email = $email; $this->mobile = $mobile; //business handle and register success $reg_result = true; if ($reg_result) { $this->notify(); // 注册成功 所有的观察者将会收到此主题的通知 return true; } return false; } /** * 当前主题注册新的观察者 * @param SplObserver $observer [description] * @return [type] [description] */ public function attach(SplObserver $observer) { return array_push($this->observers, $observer); } /** * 当前主题删除已注册的观察者 * @param SplObserver $observer [description] * @return [type] [description] */ public function detach(SplObserver $observer) { $key = array_search($observer, $this->observers, true); if (false !== $key) { unset($this->observers[$key]); return true; } return false; } /** * 状态更新 通知所有的观察者 * @return [type] [description] */ public function notify() { if (! empty($this->observers)) { foreach ($this->observers as $key => $observer) { $observer->update($this); } } return true; }}

Email/Sms 观察者

/** * 观察者通过 update 来接受主题的更新通知 */class EmailObserver implements SplObserver{    /**     * 观察者接收主题通知的接口     * @param  SplSubject $user [description]     * @return [type]           [description]     */    public function update(SplSubject $user)    {        echo "send email to " . $user->email . PHP_EOL;    }}class SmsObserver implements SplObserver{    public function update(SplSubject $user)    {        echo "send sms to " . $user->mobile . PHP_EOL;    }}

业务

// User 主题$user = new User();// 为 user 注册 Email 观察者 (Email 观察者订阅 User 主题)$emailObserver = new EmailObserver();$user->attach($emailObserver);// 为 user 注册 Sms 观察者 (Sms 观察者订阅 User 主题)$smsObserver = new SmsObserver();$user->attach($smsObserver);// 从 user 上删除 Sms 观察者 (Sms 观察者取消订阅 User 主题)//$user->detach($smsObserver);// register 中会根据注册结果通知观察者 观察者做相应的处理$user->register("big cat", "32448732@qq.com", "1888888888");

结果

send email to 32448732@qq.comsend sms to 1888888888[Finished in 0.1s]

其实观察者模式类似于事件注册和钩子回调,日常开发中我们可能重构分离出一部分类的行为到外部,封装成独立的功能模块,在注册到类中,可以使用事件注册,也可以使用观察者模式

转载地址:http://bpkix.baihongyu.com/

你可能感兴趣的文章
Android 集成支付宝支付详解
查看>>
SQL分布式查询、跨数据库查询
查看>>
C#------连接SQLServer和MySQL字符串
查看>>
Arcgis Licensemanager 不能启动的原因之一(转载)
查看>>
(原)Android在子线程用handler发送的消息,主线程是怎么loop到的?
查看>>
$digest already in progress 解决办法——续
查看>>
虚拟机 centos设置代理上网
查看>>
Struts2中Date日期转换的问题
查看>>
mysql 数据类型
查看>>
Ubuntu 设置当前用户sudo免密码
查看>>
设置tomcat远程debug
查看>>
android 电池(一):锂电池基本原理篇【转】
查看>>
Total Command 常用快捷键
查看>>
ionic 调用手机的打电话功能
查看>>
怎么使用阿里云直播服务应用到现在主流直播平台中
查看>>
Xcode全局替换内容,一键Replace
查看>>
1000 加密算法
查看>>
exif_imagetype() 函数在linux下的php中不存在
查看>>
Ruby的case语句
查看>>
Linux的链接文件-ln命令
查看>>