观察者模式Laravel的Event事件系统提供了一个简单的观察者模式实现,可以订阅和监听应用中发生的各种事件,在PHP的标准库(SPL)中甚至提供了三个接口SplSubject,SplObserver,和SplObjectStorage让开发者更容易实现观察者模式,但是我还是想脱离SPL提供的接口和具体的编程语言来谈谈如何通过面向对象编程来实现观察者模式,该示例是PHP代码,但在其他面向对象语言中的实现是相同的。模式定义观察者模式(ObserverPattern):定义了对象之间一对多的依赖关系,这样每当一个对象状态发生变化时,其相关的依赖对象就会得到通知并自动更新。观察者模式也称为发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听(Source/Listener)模式或从属(Dependents)模式。观察者模式的核心在于Subject和Observer接口。Subject(主题目标)包含一个给定的状态。观察者“订阅”主题并通知观察者主题的当前状态。每次给定状态发生变化时,所有观察者都会收到通知。变化的对象称为观察目标,通知的对象称为观察者。一个观察目标可以对应多个观察者,这些观察者之间没有关联。可以根据需要添加和删除观察者,使系统更易于扩展。模式结构描述Subject对象抽象类ConcreteSubject具体对象Observer观察者抽象类ConcreteObserver具体Observer应用实例例如设置用户状态(subject)后发送当前状态描述信息到用户邮箱和手机,我们可以使用两个观察者订阅用户的状态。一旦设置了状态,主题将通知已订阅状态更改的观察者。在两个观察者中,我们可以分别实现发送邮件信息和短信信息的功能。抽象类Subject{protected$stateNow;保护$observers=[];publicfunctionattach(Observer$observer){array_push($this->observers,$observer);}publicfunctiondetach(Observer$ob){$pos=0;foreach($this->observersas$viewer){if($viewer==$ob){array_splice($this->observers,$pos,1);}}$pos++;}}publicfunctionnotify(){foreach($this->observersas$viewer){$viewer->update($this);}}}在抽象类中,attachdetach和notify都是具体的方法。这些方法只能通过继承来使用,并且会被的子类使用的Subject使用。具体目标类classConcreteSubjectextendsSubject{publicfunctionsetState($state){$this->stateNow=$state;$this->通知();}publicfunctiongetState(){return$this->stateNow;}}abstractionObserverabstractclassObserver{abstractpublicfunctionupdate(Subject$subject);在抽象观察者中,抽象方法更新等待子类为其提供具体实现。具体观察者类ConcreteObserverDTextendsObserver{private$currentState;publicfunctionupdate(Subject$subject){$this->currentState=$subject->getState();}echo'
