设计模式之观察者模式 浏览次数:216 日期:2020-08-04 18:11:42 ### 定义 观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。在观察者模式中,可以有任意数目的观察者订阅并接收通知。观察者模式中有两个重要得角色:观察者和被观察者,被观察者在观察者模式中一般叫主题。举例来说,我们大家都会关注微信公众号,比如你关注了"Json的博客"的公众号,那你就成了这个公众号的观察者,小王也关注了这个公众号,则小王也成了观察者,而这个公众号就是所谓的被观察者,也就是观察者模式中的主题。 ### 角色 - 抽象主题(Subject) 抽象主题定义具体主题的抽象方法,提供约定,可以增加和删除观察者对象。 - 具体主题(Concrete Subject) 实现抽象主题提供的方法,包括实现添加、删除观察者对象。 - 抽象观察者(Observer): 为所有的具体观察者定义接口,在得到主题通知时更新自己。 - 具体观察者(Concrete Observer): 实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调 ### 代码 ```php element[get_class($observer)] = $observer; } public function remove(Observer $observer) { unset($this->element[get_class($observer)]); } public function notify($message) { foreach($this->element as $observer) { $observer->execute($message); } } } class JsonObserver implements Observer { public function execute($message) { echo "我叫Json,我收到了消息:".$message; } } class WangObserver implements Observer { public function execute($message) { echo "我叫小王,我收到了消息,但是内容我不想告诉你"; } } ``` 客户端使用方式: ```php $subject = new MessageSubject; //添加观察者 $jsonObserver = new JsonObserver; $subject->add($jsonObserver); $wangObserver = new WangObserver; $subject->add($wangObserver); //通知 $subject->notify("我发布新文章了,快来看看吧!文章内容:我不是大牛,只是多写了几年代码而已!"); $subject->remove($wangObserver); $subject->notify("我又发布新文章了,快来看看吧!"); ``` 上面就是实现了观察者模式的全部代码,可以看到我们可以无限添加观察者,之后主题更新会给所有观察者发消息,也可以根据情况删除观察者,删除之后,被删除的观察者不再收到消息。 ### 分类 - 推模式: 主题对象向观察者主动推送消息,不管观察者是否需要。 - 拉模式:主题对象在通知观察者的时候,只传递少量信息或者不传信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取。 ### 推模式观察者 其实上面的例子就是一个推模式的观察者,我不管JsonObserver、WangObserver是否需要消息的具体内容,反正主题向观察者推送了,至于观察者需不需要就是观察者自己的事情了,例如下面的WangObserver并不输出收到的消息内容,而是自己定义了输出。 ### 拉模式观察者 ```php element[get_class($observer)] = $observer; } public function remove(Observer $observer) { unset($this->element[get_class($observer)]); } public function notify() { foreach($this->element as $observer) { $observer->execute($this); } } public function getMessage() { return "我发布新文章了,快来看看吧"; } } class JsonObserver implements Observer { public function execute($obj) { echo "我叫Json,我收到了消息:".$obj->getMessage(); } } class WangObserver implements Observer { public function execute($obj) { echo "我叫小王,我收到了消息,但是内容我不关心"; } } ``` 调用方式代码: ```php $subject = new MessageSubject; //添加观察者 $jsonObserver = new JsonObserver; $subject->add($jsonObserver); $wangObserver = new WangObserver; $subject->add($wangObserver); //通知 $subject->notify(); $subject->remove($wangObserver); $subject->notify(); ``` 可以看到拉模式的观察者模式,不会主动推送消息,而是如果观察者需要,则自己去拉取消息。 最后更新时间为: 4个月前 (2020-08-04 18:11:42)