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

PHP设计模式之观察者模式

时间:2023-03-29 23:57:47 PHP

使用场景假设项目经理让我们写一个登录界面。写完之后让我们统计第二天的登录次数,然后在后面加上代码,让我们判断第三天的登录区,在后面加上代码。第四天,让我们在用户登录后推送activity,然后添加后面的代码。第N天,这个界面乱七八糟,没人愿意维护。我们需要保持项目高内聚低耦合。可以使用观察者模式(不是必须的,看需求)。观察者的概念,观察者,首先要有一个被观察的角色,这是独一无二的,然后就会有无数的观察者来看她,可以说是一群人在看一个人。既然有无数的观众,那肯定有什么东西可以记录有哪些观众。那么应该有一个类似于存储所有观察者的数组。总结就是一个被观察者,无数个Observer,还有一个容器记录代码示例interfaceexample//SubjectinterfaceinterfaceSubject{publicfunctionregister(Observer$observer);publicfunctionnotify();}//观察者接口interfaceObserver{publicfunctionwatch();}Subject是观察者,Observer是观众,即观察者是观察者//ObserverclassActionimplementsSubject{public$_observers=数组();publicfunctionregister(Observer$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();