原文地址:zhuanlan.zhihu.com/p/51357583
做者:柳树面试
有一回面试,面试官问:编程
观察者模式,和发布订阅模式,有什么区别?设计模式
我脑海中马上闪现了《Head First设计模式》里讲的:app
Publishers + Subscribers = Observer Pattern设计
“哼哼,我知道答案了,兄dei!”,我心里无比鸡冻。code
“它们是同样的。”,我故做镇定,嘴角露出一丝微笑,仿佛下一秒钟面试官就会给我发offer。cdn
面试官也笑了,“不,它们不同”。server
而后我就:中间件
So, 为何我错了?观察者模式(Observer pattern),和发布订阅模式(Publish–subscribe pattern),到底有什么不一样?对象
所谓观察者模式,其实就是为了实现松耦合(loosely coupled)。
用《Head First设计模式》里的气象站为例子,每当气象测量数据有更新,changed()
方法就会被调用,因而咱们能够在changed()
方法里面,更新气象仪器上的数据,好比温度、气压等等。
可是这样写有个问题,就是若是之后咱们想在changed()
方法被调用时,更新更多的信息,好比说湿度,那就要去修改changed()
方法的代码,这就是紧耦合的坏处。
怎么解决呢?使用观察者模式,面向接口编程,实现松耦合。
观察者模式里面,changed()
方法所在的实例对象,就是被观察者(Subject,或者叫Observable),它只需维护一套观察者(Observer)的集合,这些Observer实现相同的接口,Subject只须要知道,通知Observer时,须要调用哪一个统一方法就行了:
这里就不贴代码了,网上已经有大量的资料。
大概不少人都和我同样,以为发布订阅模式里的Publisher,就是观察者模式里的Subject,而Subscriber,就是Observer。Publisher变化时,就主动去通知Subscriber。
其实并非。
在发布订阅模式里,发布者,并不会直接通知订阅者,换句话说,发布者和订阅者,彼此互不相识。
互不相识?那他们之间如何交流?
答案是,经过第三者,也就是在消息队列里面,咱们常说的经纪人Broker。
发布者只需告诉Broker,我要发的消息,topic是AAA;
订阅者只需告诉Broker,我要订阅topic是AAA的消息;
因而,当Broker收到发布者发过来消息,而且topic是AAA时,就会把消息推送给订阅了topic是AAA的订阅者。固然也有多是订阅者本身过来拉取,看具体实现。
也就是说,发布订阅模式里,发布者和订阅者,不是松耦合,而是彻底解耦的。
放一张极简的图,给你们对比一下这两个模式的区别:
从表面上看:
往更深层次讲:
从使用层面上讲:
最后,个人全部文字,都是对这篇文章的拙劣模仿:Observer vs Pub-Sub pattern