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

观察者模式总结

时间:2023-03-29 14:42:37 PHP

什么是观察者模式观察者模式用于观察对象:一旦主体对象的状态发生变化,与其关联的观察者对象就会收到通知,并执行相应的操作。我举个例子:假设这样一种情况,公司有一个新员工,在入职当天,HR需要为他办理入职手续。.传统的编程方式是直接在员工入职事件的代码后面添加处理逻辑。当我们后面需要增加处理逻辑时(比如员工入职后增加培训),代码就会变得难以维护。这种方法是耦合的和侵入性的。添加新逻辑需要更改事件主题的代码。使用观察者模式,将员工的入职视为一个事件,其他处理逻辑作为观察者的操作。那么以后需要添加更多逻辑的时候,添加逻辑代码会非常方便。具体代码实现如下。代码实现首先定义一个观察者接口,所有的观察者都实现这个接口(为什么要定义为接口?因为需要具体实现每个观察者的具体行为,用接口定义统一的方法,而具体实现交给观察者来实现)interfaceobserver{publicfunctionupdate();}然后定义一个事件生成器的抽象类,用来让从它继承的事件具有通知观察者的能力。抽象类EventGenerator{private$observers=[];//定义一个添加观察者的方法publicfunctionaddOberver(Observer$observer){$this->observers[]=$observer;}//定义一个通知观察者的方法publicfunctionnotify(){foreach($this->observersas$observer){$observer->update();}}}然后定义事件类classeventextendsEventGenerator{//定义一个方法来触发观察者publicfunctiontrigger(){echo"Event
";//开始通知观察者$this->notify();}}开始使用$event=newevent();$event->trigger();这时候,当我们想在事件发生时添加其他操作时,只需要添加一个观察者即可。添加一个观察者类Observer1implementsObserver{publicfunctionupdate(){echo"Operation1
";然后在使用的时候是$event=newevent();//添加观察者$event->addObserver(newObserver1);$event->trigger();如果需要在事件发生后添加操作,只需renew添加相应的观察者即可。应用观察者模式的好处观察者模式将主体与具体的观察者解耦,让耦合的双方都依赖于抽象而不是具体。这样,每一次改变都不会影响到另一边的改变。降低对象之间的耦合度,达到解耦的目的,符合“开闭原则”的要求。使用SPL实现观察者模式PHP通过内置的SPL扩展提供了对观察者模式的原生支持,其中观察者由3个元素组成:SplObserver接口、SplSubject接口和SplObjectStorage工具类。下面是使用SPL实现观察者模式的代码。SPL的地址在这里。类MyObserver1实现SplObserver{publicfunctionupdate(SplSubject$subject){echo__CLASS__。'-'。$subject->getName();}}classMyObserver2实现SplObserver{publicfunctionupdate(SplSubject$subject){echo__CLASS__.'-'。$subject->getName();}}类MySubject实现SplSubject{private$observers;私人的名字;公共函数__construct($name){$this->observers=newSplObjectStorage();$this->name=$name;}publicfunctionattach(SplObserver$observer){$this->observers->attach($observer);}publicfunctiondetach(SplObserver$observer){$this->observers->detach($observer);}publicfunctionnotify(){foreach($this->observersas$observer){$observer->update($this);}}publicfunctiongetName(){return$this->name;}}$observer1=newMyObserver1();$observer2=newMyObserver2();$subject=newMySubject("test");$subject->attach($observer1);$subject->attach($observer2);$subject->notify();/*输入:MyObserver1-testMyObserver2-test*/$subject->detach($observer2);$subject->notify();/*输入:MyObserver1-test*/