设计方案--浅析观察者模式和发布-订阅模式的区别

数据工
• 阅读 1934

有时候面试的时候可能会被问到:

观察者模式和发布订阅模式的区别?

没有区别吧?

好像有区别吧?

我们首先来看一下“观察者模式”和“发布订阅模式”

一、观察者设计模式

理解设计模式在设计之初的是为了解决什么问题就能很好的在写代码中运用不同的设计模式。

所谓的观察者模式,其实为了实现松耦合(loosely coupled),也就是为了解耦。

当数据有变化有更新的时候,某个方法被调用,这时候就可以更新其他地方需要用到这个数据的地方。

举个例子:

以气象站为例,每当气象站测试数据有更新的时候,changed()方法都会被调用,于是我们在changed()方法中,更新气象仪器上的数据,比如温度、气压等等。

这样写没有毛病,但是,如果我们以后再changed()方法调用的时候,更新更多的信息,比如说湿度,这个时候我们需要去修改changed()方法的代码,这个就是紧耦合的坏处。

那怎么解决这个紧耦合的问题呢?

观察者模式中,changed()方法所在的实例对象,就是被观察者(subject),只需要维护一套观察者(observer)的集合,这些observer实现相同的接口,subject只需要知道:通知观察者(observer)时,需要调用哪一个统一方法就行。
设计方案--浅析观察者模式和发布-订阅模式的区别

我们再来看一下简单的例子

function Subject(){
    this.observerData = [];
}
Subject.prototype = {
    add: function(observer) {
        this.observerData.push(observer);
    },
    remove:function(observer) {
        var observerData = this.observerData;
        for(let i=0,length=observerData.length;i<length;i++){
            if(observerData[i] === observer){
                observerData.splice(i,1)
            }
        }
    },
    notify: function() {
        var observerData = this.observerData;
        for(let i=0,length=observerData.length;i<length;i++){
            observerData[i].update();
        }
    }
}

function Observer(name){
    this.name = name;
}

Observer.prototype = {
    update: function() {
        console.log('hello,' + this.name);
    }
}

var sub = new Subject();

var obj1 = new Observer('saucxs');
var obj2 = new Observer('songEagle');

sub.add(obj1);
sub.add(obj2);
sub.notify();

这时候输出的是

hello,saucxs

hello,songEagle

上述代码中,我们创建了Subject对象和两个Observer对象,当前状态发生变更的时候则通过Subject对象的notify方法通知两个Observer队形,这两个Observer对象通过update方法进行更新。

二、发布订阅模式(Publisher && Subscriber)

其实觉得发布订阅模式里的Publisher,就是观察者模式的Subject,而Subscriber就是Observer。Publisher变化的时候,就会主动去通知Subscriber。

其实并不是这样的。

在发布订阅模式里,发布者并不会直接通知订阅者,换句话说,发布者和订阅者,彼此互补相识。

那他们之间如何进行通信的?是通过第三者,就是在消息队列中,我们常说的经纪人Broker。

设计方案--浅析观察者模式和发布-订阅模式的区别

发布者只需要告诉Broker,我要发消息。topic是“saucxs”

订阅者只需要告诉Broker,我要订阅topic是“saucxs”

于是,当Broker接收到发布者发来的消息,并且topic是saucxs的时候,就会把消息推送到订阅了topic的saucxs的订阅者,也可能是订阅者自己过来拉取,具体看代码实现。

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

放一张很简单的图,对比一下两个模式的区别:

设计方案--浅析观察者模式和发布-订阅模式的区别

三、总结

表面上看:

1、观察者模式中,两个角色:观察者和被观察者

2、发布订阅模式中,三个角色:发布者,订阅者,经纪人

深层次的看:

1、观察者模式:观察者和被观察者,是松耦合的关系

2、发布订阅模式:发布和订阅者是完全不存在耦合的

从使用层面上看:

1、观察者模式:多用于单个应用内部,维护的是单一事件对应多个依赖的

event -> [obj1,obj2,obj3,....]
2、发布订阅模式:多用于跨应用的模式,比如我们说的消息的中间件,维护的是多个事件以及依赖的

event1 -> [obj1,obj2,...]
event2 -> [obj1,obj3,...]

点赞
收藏
评论区
推荐文章
观察者模式在spring中的应用
作者:王子源1观察者模式简介1.1定义指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布订阅模式、模型视图模式,它是对象行为型模式。
Wesley13 Wesley13
3年前
java设计模式详细讲解
原文链接:java设计模式详细讲解观察者模式(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.blogchina.cn%2Fblog%2Fguopengfei%2Fhome%2F270%2F1575725711626"java设计模式详细讲解观察者模式")如果想要更加
尼克 尼克
4年前
简说设计模式——观察者模式
一、什么是观察者模式  观察者一般可以看做是第三者,比如在学校上自习的时候,大家肯定都有过交头接耳、各种玩耍的经历,这时总会有一个“放风”的小伙伴,当老师即将出现时及时“通知”大家老师来了。再比如,拍卖会的时候,大家相互叫价,拍卖师会观察最高标价,然后通知给其它竞价者竞价,这就是一个观察者模式。  对于观察者模式而言,肯定有观察
Stella981 Stella981
3年前
Guava — EventBus
Guava提供了事件总线的一个实现方案EventBus。它是事件发布订阅模式的实现,观察者模式。Guava为我们提供了同步实现EventBus和异步实现AsyncEventBus两个事件总线,他们都不是单例的eventBus.post(1);eventBus.post(1L);post方法,直接发布事件订阅者需要注册进来,ev
Stella981 Stella981
3年前
Android面试之EventBus
简介众所周知,EventBus是一款用在Android开发中的发布/订阅事件总线框架,基于观察者模式,将事件的接收者和发送者分开,简化了组件之间的通信操作,使用简单、效率高、体积小!EventBus使用了典型的发布/订阅事件模式,下面是EventBus官方给出的原理示意图。!在这里插入图片描述(https://oscimg.o
Stella981 Stella981
3年前
Guava中的EventBus
其实代码中经常会遇到跟主流程分支出去的异步逻辑,比如说:爬虫处理逻辑中,进行心跳打点,订单处理中,需要触发用户的个人信息变更等。这个时候就应该使用观察者模式。EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式,EventBus是一个非常优雅和简单解决方案,我们不用创建
Easter79 Easter79
3年前
Spring中ApplicationContext的事件机制
   ApplicationContext事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件处理。如果容器中有一个ApplicationListenerBean,每当ApplicationContext发布ApplicationEvent时,
Wesley13 Wesley13
3年前
Java描述设计模式(11):观察者模式
本文源码:GitHub·点这里(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fcicadasmile%2Fmodelarithmeticparent)||GitEE·点这里(https://gitee.com/cicadasmile/modela
Wesley13 Wesley13
3年前
Java Design Patterns
java的设计模式大体上分为三大类:创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模
Wesley13 Wesley13
3年前
PHP观察者模式
其实不用刻意去学习模式,我们平常看代码,写代码的过程中已经接触或使用过不少设计模式,只是我们不知道罢了。但是我们仍然需要了解一下书上的说法,对比印证一下,加深理解。本文说的是设计模式:观察者模式根据字面意思理解,我们知道关键字是“观察”两个字,这是一个动词,那么就需要有"被观察者"和"观察者"。举个栗子:公司有一台很重要的线上服务器,以及一个
Wesley13 Wesley13
3年前
unity工程师面试知识点之MVC架构+观察者模式
所谓设计模式通俗点理解就是解决固定问题的套路。而说起观察者模式又不得不提起客户端框架设计中最常用的实现逻辑:MVC架构观察者模式。MVC架构中的M、V、C分别是model、view、control的缩写。model:模型,处理数据逻辑部分view:界面,处理数据显示部分control:控制器,模型和界面的沟通桥梁,负责从视图读取数据,控制用
数据工
数据工
Lv1
所有的快乐,都来源于生活的心动。
文章
3
粉丝
0
获赞
0