深入 Laravel 内核之观察者模式
装饰模式核心内容:
- 观察者模式又称为发布订阅模式,定义了对象间的一对多依赖关系,当一个对象状态发生改变时,其相关依赖的其他对象都能接收到通知;
- 观察者模式的核心在于目标(Subject)和观察者(Observer)接口,目标有一个状态属性,观察者“订阅”这个目标,当目标的状态属性发生改变时,通知所有观察者。
- 目标状态改变只需核心业务逻辑并调用通知接口,无需关心具体的观察者及其数量,降低对象之间的耦合度;
定义一个目标抽象类,提供绑定&解绑观察者的接口供客户端使用,提供通知观察者的接口供目标实现类使用:
abstract class Subject
{
protected $stateNow;
protected $observers = [];
public function attach(Observer $observer)
{
echo __CLASS__ . "绑定观察者:" . $observer->getClassName() . "\n\r";
array_push($this->observers, $observer);
}
public function detach(Observer $observer)
{
$pos = 0;
foreach ($this->observers as $viewer) {
if ($viewer == $observer) {
array_splice($this->observers, $pos, 1);
}
$pos++;
}
}
public function notify()
{
foreach ($this->observers as $viewer) {
echo __CLASS__ . "通知观察者:" . $viewer->getClassName() . "\n\r";
$viewer->update($this);
}
}
}
定义一个目标实现类,实现状态的变更业务:
class ConcreteSubject extends Subject
{
public function setState($state)
{
echo __CLASS__ . "修改状态并调用 notify 方法\n\r";
$this->stateNow = $state;
$this->notify();
}
public function getState()
{
return $this->stateNow;
}
}
定义一个观察者抽象类,规范接收通知的接口:
abstract class Observer
{
abstract public function update(Subject $subject);
abstract public function getClassName();
}
定义两个观察者实现类,实现接收通知的业务逻辑:
class ConcreteObserverEmail extends Observer
{
//维护一个指向具体目标对象的引用
private $currentState;
public function update(Subject $subject)
{
$this->currentState = $subject->getState();
echo $this->getClassName() . "收到了通知,内容为:" . $this->currentState . "\n\r";
}
public function getClassName() {
return __CLASS__;
}
}
class ConcreteObserverPhone extends Observer
{
//维护一个指向具体目标对象的引用
private $currentState;
public function update(Subject $subject)
{
$this->currentState = $subject->getState();
echo $this->getClassName() . "收到了通知,内容为:" . $this->currentState . "\n\r";
}
public function getClassName() {
return __CLASS__;
}
}
定义一个客户端,给目标绑定观察者,查看效果:
class Client
{
public function main()
{
$sub = new ConcreteSubject();
$obEmail = new ConcreteObserverEmail();
$obPhone = new ConcreteObserverPhone();
$sub->attach($obEmail);
$sub->attach($obPhone);
$sub->setState('开启');
}
}
(new Client())->main();
输出结果:
Subject绑定观察者:ConcreteObserverEmail
Subject绑定观察者:ConcreteObserverPhone
ConcreteSubject修改状态并调用 notify 方法
Subject通知观察者:ConcreteObserverEmail
ConcreteObserverEmail收到了通知,内容为:开启
Subject通知观察者:ConcreteObserverPhone
ConcreteObserverPhone收到了通知,内容为:开启
深入 Laravel 内核之观察者模式的更多相关文章
- 深入 Laravel 内核之IOC容器
升级工厂前的准备工作 无规矩不成方圆,随着越来越多的行为出现,我们需要需要定下一些规范. 为了约束每一个行为的规范,需要定义一个行为接口: interface BehaviorInterface { ...
- 深入 Laravel 内核之工厂模式
英雄与行为,依赖的诞生 首先定义一个英雄,英雄具有一些行为: class Hero { protected $behavior = []; public function show() { var_d ...
- 深入 Laravel 内核之装饰模式
装饰模式核心内容: 装饰模式可以在不影响组件对象的情况下,以动态.透明的方式从外部给对象添加功能: 装饰器模式的本质就是动态组合.动态是手段,组合是目的.装饰模式是通过把复杂的功能简单化.分散化,在运 ...
- 深入 Laravel 内核之外观模式(门面模式)
门面模式核心内容: 客户端与子系统的通信通过外观对象进行: 外观对象封装一系列子系统的具体对应方法,对客户端只需暴露一个单一的入口方法: 客户端通过访问外观对象即可调用子系统的基础方法,无需关心子系统 ...
- 深入 Laravel 内核之 PHP 反射机制和依赖注入
结论: PHP中提供了反射类来解析类的结构: 通过反射类可以获取到类的构造函数及其参数和依赖: 给构造函数的参数递归设置默认值后,即可使用这些带默认值的参数通过 newInstanceArgs 实例化 ...
- laravel 实现思路以及各组件原理
laravel 内核是个IOC容器,IOC是把本来自己实例化的对象. 通过在容器里注册,通过容器来进行实例化. laravel队列用的是redis的列表来实现.
- Laravel 从入门到精通系列教程
转载;https://laravelacademy.org/laravel-tutorial-5_7 适用于 Laravel 5.5.5.6.5.7 版本,本系列教程将围绕一个 LTS 版本,然后采取 ...
- Laravel源码解析之从入口开始
前言 提升能力的方法并非使用更多工具,而是解刨自己所使用的工具.今天我们从Laravel启动的第一步开始讲起. 入口文件 laravel是单入口框架,所有请求必将经过index.php define( ...
- Laravel核心解读--Contracts契约
Contracts Laravel 的契约是一组定义框架提供的核心服务的接口, 例如我们在介绍用户认证的章节中到的用户看守器契约IllumninateContractsAuthGuard 和用户提供器 ...
随机推荐
- my42_Mysql基于ROW格式的主从同步
模拟主从update事务,从库跳过部分update事务后,再次开始同步的现象 主库 mysql> select * from dbamngdb.isNodeOK; +----+--------- ...
- 【Service】【Database】【MySQL】基础
1. 概念 1.1. 作者:Unireg 1.2. MySQL AB --> MySQL Solaris:二进制版本: 1.3. 官方网站: MySQL: www.mysql.com Maria ...
- show_slave_status参数详解
#这个是指slave 连接到master的状态 #当前在等待主发送事件 Slave_IO_State: Waiting for master to send event #master地址 Maste ...
- Jenkins监控
目录 一.Monitoring插件 二.Prometheus监控 一.Monitoring插件 Monitoring插件(monitoring)使用JavaMelody,对Jenkins进行监控.插件 ...
- react功能实现-组件创建
这里主要从两个角度来分析创建一个组件需要怎么做,一个是元素,一个是数据.整理向,大量借鉴,非原创. 1.渲染组件. 我们先明确一点,所有的元素都必须通过render方法来输出渲染.所有,每个组件类最终 ...
- iNeuOS工业互联网操作系统,发布3.6.4版本:云端安全控制和实时日志功能,附Chrome、Firefox和Edge浏览器测试性能对比
目 录 1. 概述... 2 2. 平台演示... 2 3. 云端控制和实时日志设计和技术... 2 4. 实时日志测试... 2 1. 概述 ...
- Linux 三剑客之sed
目录 Linux 三剑客之sed 命令补充: sort命令 uniq命令 cut命令 tr命令 wc命令 三剑客 - sed 编辑模式: 定位分类: 实例如下: d模式--删除模式 p模式--打印 a ...
- bootstrap.css 进度条没有动画效果
操作系统设置会影响浏览器的行为 Win+R 输入 sysdm.cpl ,3 打开 性能 的 设置 确保 窗口内动画控件和元素 被勾选
- 5、双指针技巧套路框架——Go语言版
前情提示:Go语言学习者.本文参考https://labuladong.gitee.io/algo,代码自己参考抒写,若有不妥之处,感谢指正 关于golang算法文章,为了便于下载和整理,都已开源放在 ...
- socket网络编程基础模块
更多功能 sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0) 参数一:地址簇 socket.AF_INET IPv4(默认) socket. ...