PHP设计模式|观察者模式
时间:2022-07-22
本文章向大家介绍PHP设计模式|观察者模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
使用场景
假设项目经理让我们写了一个登陆接口,咔咔擦擦写完了
- 第二天让我们加入统计登陆次数,然后在后面加代码
- 第三天让我们判断登陆地区,又在后面加代码
- 第四天让我们在用户登陆后推送活动,再再后面加代码
- 第N天,这个接口已经杂乱到没人想维护了
我们需要让项目保持高内聚低耦合,就可以用到观察者模式(也不是非要,看需求)
概念
观察者,观察者,首先要有个被人观察的角色,这是唯一的,然后会有无数个观察者去看她,可以说是一群人在围观一个人,既然有无数个观众,那总得有个东西记录有哪些观察者,那就应该有一个类似于数组一样来储存所有观察者,总结就是一个被观察者,无数个观察者,再有一个容器记录
代码示例
- 接口示例
// 主题接口
interface Subject{
public function register(Observer $observer);
public function notify();
}
// 观察者接口
interface Observer{
public function watch();
}
Subject就是被观察者,Observer就是观众,也就是观察者
被观察者
// 被观察者
class Action implements Subject{
public $_observers=array();
public function register(Observer $observer){
$this->_observers[]=$observer;
}
public function notify(){
foreach ($this->_observers as $observer) {
$observer->watch();
}
}
}
Action实现了被观察者接口,他现在就是被观察者,再定义一个$_observers数组,他就是记录观众的容器了。
首先实现register方法,用它传入一个观察者,然后塞到数组里,再实现notify()方法,它会遍历容器数组,执行每个观察者的watch()方法。
观察者
// 观察者
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会循环调用每个观察者的watch()方法,所以我们需要实现每个观察者的watch()方法。
#### 调用
// 应用实例
$action=new Action();
$action->register(new Cat());
$action->register(new People());
$action->register(new Dog());
$action->notify();
首先new被观察者对象,执行它的register()方法,把每个观察者都放入容器数组,最后执行notify()方法,通知所有观察者执行自己的方法。
PHP原生自带的观察者模式
PHP有自带的观察者模式
- splsubject接口 - 被观察者
- Observer接口 - 观察者
- SplObjectStorage对象 - 容器
首先我们有一个用户登录类
class user{
public function login()
{
echo '登录完毕'
}
让他实现splsubject接口成为被观察者。
- 首先在构造函数里,让他new SplObjectStorag()对象并赋值到属性上方便后面调用
- 实现attach()方法,用来注册观察者
- 实现detach()方法,用来删除观察者
- 实现notify()方法,用来遍历容器,调用每个观察者的update方法(必须是update)
- rewind方法是容器指针重置到最开始,valid方法检测容器是否遍历完成并返回布尔,current方法是获取当前的观察者,next方法是将指针后移一位
- 修改login()方法,在里面调用notify()来通知观察者事件完成了
class user implements splsubject{
protected $observer = null;
public function __construct()
{
$this->observer = new SplObjectStorage();
}
public function login()
{
$this->notify();
echo '登录完毕';
}
public function attach(SplObserver $observer)
{
$this->observer->attach($observer);
}
public function detach(SplObserver $observer)
{
$this->observer->detach($observer);
}
public function notify()
{
$this->observer->rewind();
while ($this->observer->valid())
{
$observer = $this->observer->current();
$observer->update($this);
$this->observer->next();
}
}
}
观察者
每个观察者实现SplObserver接口,并实现update()方法
class cat implements SplObserver {
public function update(SplSubject $subject)
{
echo '小猫叫一下';
}
}
class dog implements SplObserver {
public function update(SplSubject $subject)
{
echo '小狗吼一声';
}
}
应用
// 实时观察
$user = new user();
$user->attach(new cat());
$user->attach(new dog());
$user->login();
- Enterprise Library 4 缓存应用程序块的设计
- 让WordPress 在RSS 中Feed 输出支持“More”标签
- WordPress文章版权保护:复制文字自动添加版权信息
- 替换WordPress 自带默认的 jQuery库, jQuery库页脚加载
- Enterprise Library 4 数据访问应用程序块
- 替换EnterPrise Library 4.0 缓存应用程序块的CacheManager
- Enterprise Library 4.0缓存应用程序块
- 通过.htaccess 让WordPress 的上传文件夹更安全
- asp.net 性能调较
- 零基础学习大数据,搭建Hadoop处理环境
- 为你的WordPress 博客开启两步验证功能(技术支持:谷歌)
- 为你的WordPress 博客开启两步验证功能(技术支持:谷歌)
- WordPress 注册页面显示自定义提示信息
- Windows Server 2008密码重设盘
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC
- 如何有效恢复误删的HDFS文件
- 别再用OFFSET和LIMIT分页了
- 别再用大小比较时间了
- Redis快速入门
- 捉虫记:Unexpected end of JSON input while parsing
- 重新思考日志:业务系统竟然是一个大数据库?
- 测试面试题集-Linux常用命令
- 「真香警告」鱼头手摸手教你在小程序里用composition-api
- 【技术文】SSL握手中的几个密码
- 分布式监控系统SkyWalking
- 文献笔记二十九:银合欢(Leucaena trichandra)线粒体基因组
- Docker Swarm群集配置实战——第一战
- 文献笔记五十:vcf2poptree根据vcf文件构建进化树的网页工具
- typescript基础篇(6):泛型
- Flutter 初学者必读的高级布局规则