PHP 软件开发:设计模式 |观察者模式(Observer)分析与应用
使用场景
假设项目经理让我们写一个登录界面,咔咔写完了
- 我们第二天添加统计登录,然后添加代码吧 【观察者结构图】

概念
(观察者),首先被观察的必须是角色,但他是【独一无二】的。虽然只有一个“表演者”,但有很多“观众”,即围绕着一个“人”的一群“人”。既然有无数的观察者,我们就需要知道那里有哪些“人”。所以我们需要一个“容器”来存储这些“人”,一个类似于数组的容器,里面存储了所有的观察者。
“演员”(观察者)、一群“观众”(观察者)、“相机”(存储容器)
★【我的PHP进阶学习交流社区“点击”】准备的社区专用材料的管理:来自BAT等优质厂商的高级信息系统(相关学习资料和笔试题)包括但不限于:分布式架构、高扩展性、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft 、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等诸多数据点,进阶进阶的数据
【观察者模式下角色的主要】
- 抽象主题(Subject)角色:主题角色商店对集合中观察对象的所有引用,并且每个主题可以有任意多个观察者。抽象主题提供了用于添加和删除观察者对象的用户界面。
- 抽象观察者(观察者)角色:为所有具体观察者定义一个接口,并在观察对象发生变化时自行更新。
- 具体主体(ConcreteSubject)角色:将相关状态存储在特定的观察对象中。当特定对象的内部状态发生变化时,会向所有注册的观察者发送通知。具体主体 角色 通常用具体子类来实现。
- 具体观察者(ConcretedObserver)角色:保存具体的主体对象,存储其关联状态,并实现抽象观察者角色所需的更新接口,使其自身的状态与对象的状态一致。?我们定义了登录区域,并在最后添加了代码
- 第四天,我们在用户登录后推送了该功能,然后将代码添加到了末尾
- 第N天,这个UI变得混乱不堪没有人愿意维护它
我们需要保持项目的高内聚和低连接,这样我们就可以使用观察者模式(不是必须的,根据需求而定)
[观察模式和其他模式]
1. 【中介者模型】(Mediator):ChangeManager通过封装复杂的更新语义,充当目标和观察者之间的中介。
2.【Singleton模式】(单例模式):ChangeManager可以使用Singleton模式来保证其唯一性和全局可用。
- 第三天,我们定义登录区域,然后添加代码
- 第四天,我们在用户登录后推送活动,然后添加代码
- 第N天,这个界面已经很乱了。人们想要保留它,这正在被观察到。然后就有无数的观察者来看他。可以说一群人在注视着一个人。既然有无数的观察者,就必须有一些东西来记录有观察者。那么应该有一个与所有观察者相似的数组。综上,有一个观察者,无数个观察者,一个容器记录
★ PHP高级学习交流社区“点击”管理完成 社区独家教材:高级信息系统(相关学习资料和笔试面试题)优质厂家如作为BAT,不限:分布式架构、高扩展、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等数据点、高级高级信息
代码示例
- 界面示例
// 主题接口 interface Subject{ public function register(Observer $observer); public function notify(); } // 观察者接口 interface Observer{ public function watch(); } 复制代码
主体是观察者,观察者是观众,即观察者被观察的界面被观察者,他现在被观察了,并且然后定义$_observers表,他是存储观众的容器。
首先实现register方法,用它传递观察,然后添加到数组中,然后实现notify()方法,该方法循环容器数组,执行每个观察者的watch()方法。
Observer
// 观察者 class Cat implements Observer{ public function watch(){ echo "Cat watches TV<hr/>"; } } class Dog implements Observer{ public function watch(){ echo "Dog watches TV<hr/>"; } } class People implements Observer{ public function watch(){ echo "People watches TV<hr/>"; } } 复制代码
这里定义了三个观察者,它们都实现了Observer接口。前面的Subject在循环中调用了每个watcher的watch()方法,所以我们需要实现每个watcher的watch()方法。方法。
调用
// 应用实例 $action=new Action(); $action->register(new Cat()); $action->register(new People()); $action->register(new Dog()); $action->notify(); 复制代码
首先,新的被观察对象,执行其register()方法,将每个观察者放入容器队列中,最后执行notify()方法,提示所有观察者执行自己的方法。
php 有自己内置的观察者模式
php 有自己内置的观察者模式
- splSubject 接口 - 被观察者
- ObServer 接口 - 观察者
- splobjetorage 对象 - 容器
First of all,我们有登录类
class user{ public function login() { echo '登录完毕' } 复制代码
,让他实现splsubject接口,成为观察者。
- 首先让它在构造函数中创建一个新的SplObjectStorag()对象,并将其赋值给属性以供后续调用。
- 实现attach()方法来注册观察者
- 实现detach()方法来删除观察者
- 实现notify()方法,该方法用于循环容器并调用每个观察者的update方法。 (需要更新)
- Rewind方法将容器指针返回到开头,valid方法检测容器遍历是否结束并返回一个Boolean,当前方法是获取当前观察者,下一个方法是移动将指针向后移动一位
- 编辑login()方法并在其中调用notify()来通知观察者事件结束。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。