观察者模式 vs 发布订阅模式

面试官问:

观察者模式和发布订阅模式有什么区别?

我的脑海立刻闪过《Head First设计模式:

Publishers Subscribers = Observer Pattern

哼哼,我知道答案,兄弟dei!,我心里很冷。

他们是一样的。我假装冷静,嘴角露出微笑,仿佛面试官会在下一秒给我发信息offer。

面试官也笑了,不,他们不一样。

然后我就:

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订阅者。当然也有可能是订阅者自己来拉,看具体实现。

也就是说,在发布订阅模式中,发布者和订阅者完全解耦,而不是松耦合。

放一张极简的图,给大家对比一下这两个模式的区别:

总结

从表面上看:

在观察者模式中,只有两个角色 - 观察者 被观察者发布订阅模式,但不仅是出版商和订阅者,还有一个经常被我们忽视的 - 经纪人Broker

更深层次:

观察者和观察者是松耦关系的出版者和订阅者,没有耦合

从使用层面:

观察者模式主要用于单个应用程序内部发布订阅模式,更多的是跨应用程序模式(cross-application pattern),例如,我们常用的消息中间件

最后,我所有的文字都是对这篇文章的拙劣模仿:Observer vs Pub-Sub pattern

对了,个人微信官方账号 Bridge4You,欢迎关注~

柳树絮叨

扫码免费用

源码支持二开

申请免费使用

在线咨询