假设项目经理让咱们写了一个登录接口,咔咔擦擦写完了php
次日让咱们加入统计登录次数,而后在后面加代码laravel
第三天让咱们判断登录地区,又在后面加代码面试
第四天让咱们在用户登录后推送活动,再再后面加代码sql
第N天,这个接口已经杂乱到没人想维护了shell
咱们须要让项目保持高内聚低耦合,就能够用到观察者模式(也不是非要,看需求)数组
观察者,观察者,首先要有个被人观察的角色,这是惟一的,而后会有无数个观察者去看她,能够说是一群人在围观一我的,既然有无数个观众,那总得有个东西记录有哪些观察者,那就应该有一个相似于数组同样来储存全部观察者,总结就是一个被观察者,无数个观察者,再有一个容器记录服务器
★个人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(); }
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有自带的观察者模式
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();
PHP 互联网架构师 50K 成长指南+行业问题解决总纲(持续更新)
面试10家公司,收获9个offer,2020年PHP 面试问题
★若是喜欢个人文章,想与更多资深开发者一块儿交流学习的话,获取更多大厂面试相关技术咨询和指导,欢迎加入咱们的群-点击此处。
本文由博客群发一文多发等运营工具平台 OpenWrite 发布