首先理解下什么是事件.
JS 中是有事件这个概念的,点击一下按钮然后出现个弹框,这就触发了一次点击事件,执行的内容就是出现一个弹框.那为什么能触发事件呢?那是因为我提前绑定了点击事件给按钮,所有才会有触发的可能.
这里面便包含了事件的绑定和触发过程,当然后面还会有解绑/通知等操作,这个我们一个一个说.
thinkphp6的事件机制采用了观察者模式,所以要先从什么是观察者模式说起.
"抖音上你关注了一个博主,只要博主有新的视频上传分享,抖音就会通知你,至于你看不看他和博主就没有关系了,只要有新视频,就会一直推送视频给你".这就是一个观察者模式.
观察者模式 => 博主 + 关注博主的人
它解决的是对象间一对多关系下,当主对象改变状态时,依赖对象都会收到通知并各自处理的问题,它让这两边的对象松耦合.
Talk is cheap show me the code,让我们用代码来说明下(就以抖音视频这个案例来说明).
//先来个不用观察者模式的代码
class Bloger {
public function push() {
$video = Video::where("***")->find();//找出我的最新上传的一个视频
if ($video) {
//开始通知
MrZhang.newVideo();
MrWang.newVideo();
MrsLi.newVideo();
......
}
}
}
$bloger = new Bloger();
$bloger->push();//执行发布视频操作
这样的写法在系统很小的时候会没问题,但抖音上随随便便一个博主就是上万的粉丝,这样的方法不容易扩展,耦合度太高.
如果用上观察者模式,改造上面的代码
//定义一个被观察者接口,具有添加/删除/通知观察者的功能,这样不论是哪个观察者来去,都不用再调整
interface Observed {
public function addViewer(Observer $observer);
public function delViewer(Observer $observer);
public function notify();
}
class Bloger implements Observed {
public $observers = [];//粉丝池
public function addViewer(Observer $observer) {
$key = array_search($observer,$this->observers);
if ($key === false) {
$this->observers[] = $observer;
}
}
public function delViewer(Observer $observer) {
$key = array_search($observer,$this->observers);
if ($key !== false) {
unset($this->observers[$key]);
}
}
//通知所有观察者
public function notify() {
foreach($this->observers as $observer){
$observer->update($this);
}
}
public function push() {
$video = Video::where("***")->find();//找出我的最新上传的一个视频
if ($video) {
//开始通知
$this->notify();
}
}
}
优化后的代码不再关系要具体通知谁,而是遍历粉丝池通知池内所有人,这样粉丝的变动都不会影响Bloger这个类.
//粉丝接口,所有粉丝都有一个接受通知并做处理的函数
interface Observer(){
public function update(Observed $observed);
}
//粉丝处理
class MrZhang implements Observer{
public function update(Observed $observed) {
echo '立刻看视频';
}
}
class MrWang implements Observer{
public function update(Observed $observed) {
echo '不想看,以后再说';
}
}
//具体执行过程,添加关注粉丝(也就是绑定)
$bloger = new Bloger();
$bloger->addViewer(new Mrzhang());
$bloger->addViewer(new MrWang());
$bloger->push();//发布视频
......
用观察者的思维理解下事件.有很多的观察者,他们都在监听事件是否发送,一旦被触发,这些观察者都会得到通知并做相应处理.
事件:指监听系统的某个行为,实时获取并执行自己逻辑代码的过程
为了便于理解,我们来模拟一个场景,假设有一个登录系统,登录以后需要做一些事情:本地记录日志/告诉朋友我已上线/给管理员发邮件.这个"一些事情"就很多了,未来充满了不确定性,说不好那天需求又变了(经理是处女座).所以系统一定要写的松耦合,这就要使用事件机制
.上Code
//一个标准的用户登录逻辑
class User {
public function login(){
//登录前的某些操作
User::login($username,$password);//登录操作
//登录后的某些操作
}
}
首先我们要明确观察者和被观察者,观察者有三个(本地记录日志/告诉朋友我已上线/给管理员发邮件),他们都需要登录状态这个通知,所以被观察者就是登录状态.在登录之前我们需要完成观察者的订阅(监听),登录后要完成通知(也就是事件触发),
//定义观察者订阅(监听)
class Log(){
public function update($user){
echo '我记录一条登录信息';
}
}
class Friend(){
public function update($user){
echo '朋友们,我上线了';
}
}
class Admin(){
public function update($user){
echo '向管理员发送email';
}
}
观察者代码自我执行的操作,都有一个$user形参,他会将一些事件信息传递给观察者方法.
//被观察者,完成事件监听和通知
class User {
public functin __construct(){}
//添加事件监听
Event::listen('Userlogin',['Log']);
Event::listen('Userlogin',['Friend']);
Event::listen('Userlogin',['Admin']);
}
public function login(){
//登录前的某些操作
if(false !== User::login($username,$password){
Event::trigger('Userlogin');//登录后事件触发
}
}
}
在trigger这个地方会通知所有正在UserLogin上监听的观察者执行各自的update方法.这就是事件的执行过程.
下一篇文章讲,在thinkphp6
中,这个事件机制是如何运行的.
Bug天天改,头发日日疏,码字不易,如果有帮助到你,就点击"下方感谢"支持一下把.