当前位置: 首页 > 后端技术 > PHP

PHP设计模式-观察者模式(Observer)浅析与应用

时间:2023-03-29 16:29:44 PHP

【观察者模式结构图】概念(Observer),首先要有一个被观察的角色,而ta是【唯一】。虽然“表演者”只有一个,“观众”却有很多,也就是一群“人”在看一个“人”。由于有无数的观察者,我们需要知道有哪些“人”。所以我们需要一个“容器”来记录这些“人”,一个类似于数组的容器来存放所有的观察者。一个“演员”(观察者),一组“观众”(观察者),一个“摄像机”(录像容器)我的php进阶学习交流社区【点击】管理准备社区独家资料:BAT等先-线厂商进阶知识体系(相关学习资料和笔试面试题)且不限于:分布式架构、高扩展、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等知识点进阶进阶干货【观察者模式中的主要角色】抽象主题(Subject)角色:主题角色将所有观察者对象的引用保存在一个集合中,每一个主题可以有任意数量的观察者。抽象主题提供了一个用于添加和删除观察者对象的接口。抽象观察者(Observer)角色:为所有具体的观察者定义一个接口,当观察的主体发生变化时更新自己。特定主题(ConcreteSubject)作用:将相关状态存储到特定的观察者对象中,当特定主题的内部状态发生变化时,向所有注册的观察者发送通知。具体的主题角色通常用具体的子类来实现。具体观察者(ConcretedObserver)角色:存储一个具体的主体对象,存储相关状态,实现抽象观察者角色需要的更新接口,使其自身状态与主体状态保持一致。【使用场景】假设项目经理让我们写一个登录界面。写完了,让我们统计一下第二天的登录次数,然后再添加后面的代码。第三天,让我们判断一下登录区,然后添加后面的代码。第四天,让我们在用户登录后推送activity,然后添加后面的代码。第N天,这个界面乱七八糟,没人愿意维护。我们需要保持项目高内聚低耦合,所以可以使用观察者模式(非必须,见需求)【观察者模式与其他模式】1.【中介者模式】(Mediator):通过封装复杂的更新语义,ChangeManager充当目标和观察者之间的中介。2.【单例模式】(singletonmode):ChangeManager可以使用Singleton模式,保证唯一性,全局可访问。代码示例接口示例//SubjectinterfaceinterfaceSubject{publicfunctionregister(Observer$observer);publicfunctionnotify();}//观察者接口interfaceObserver{publicfunctionwatch();}Subject是观察者,Observer是观众,即观察者是观察者//观察者类ActionimplementsSubject{public$_observers=array();公共功能寄存器(观察者$observer){$this->_observers[]=$observer;}publicfunctionnotify(){foreach($this->_observersas$observer){$observer->watch();}}}Action实现了观察者接口,他现在就是观察者,然后定义一个$_observers数组,他是记录观察者的容器。先实现register方法,用它传入一个观察者,然后塞入数组,然后实现notify()方法,会遍历容器数组,执行每个观察者的watch()方法。Observer//观察者类CatimplementsObserver{publicfunctionwatch(){echo"CatwatchesTV


";}}classDogimplementsObserver{publicfunctionwatch(){echo"DogwatchesTV
";}}classPeopleimplementsObserver{publicfunctionwatch(){echo"PeoplewatchesTV
";}}这里定义了三个观察者,都实现了Observer接口。前面的Subject会调用每个观察者的watch()方法,所以我们需要实现每个观察者的watch()方法。调用//应用程序实例$action=newAction();$action->register(newCat());$action->register(newPeople());$action->register(newDog());$动作->通知();首先new被观察对象,执行其register()方法,将每个观察者放入容器数组,最后执行notify()方法通知所有观察者执行自己的方法。PHP原生的观察者模式PHP有自己的观察者模式splsubject接口-observed观察者接口-observerSplObjectStorage对象-容器首先我们有一个用户登录类classuser{publicfunctionlogin(){echo'loginFinish'}让他实现splsubject接口并成为观察者。首先在构造函数中,让他newSplObjectStorag()对象,并赋值给属性,方便后面调用实现attach()方法,用于注册观察者实现detach()方法,并删除观察者实现notify()方法。遍历容器,调用每个观察者的update方法(必须是update)。rewind方法是将容器指针重置到开头。valid方法检测容器遍历是否完成,返回Boolean。current方法是获取当前观察者。next方法是将指针往后移一位修改login()方法,在里面调用notify()通知观察者事件完成classuserimplementssplsubject{protected$observer=null;公共函数__construct(){$this->observer=newSplObjectStorage();}publicfunctionlogin(){$this->notify();echo'登录完成';}publicfunctionattach(SplObserver$observer){$this->observer->attach($observer);}publicfunctiondetach(SplObserver$observer){$this->observer->detach($observer);}publicfunctionnotify(){$this->observer->rewind();while($this->observer->valid()){$observer=$this->observer->current();}$观察者->更新($this);$this->观察者->下一步();}}}Observer每个观察者都实现了SplObserver接口并实现了update()方法classcatimplementsSplObserver{publicfunctionupdate(SplSubject$subject){echo'小猫喵喵';}}classdogimplementsSplObserver{publicfunctionupdate(SplSubject$subject){echo'小狗咆哮';}}Application//实时观察$user=newuser();$user->attach(newcat());$user->attach(newdog());$user->login();PHP互联网架构师50K成长指南+行业解题大纲(持续更新中)面试10家公司,收到9份offer,2020年PHP面试题★如果你喜欢我的文章,如果你想和更多资深开发者交流学习,获得更多技术咨询与各大厂商访谈相关的指导,欢迎加入我们的群——点击这里