Skip to content

第 23 题:介绍下观察者模式和订阅-发布模式的区别,各自适用于什么场景 #25

Open
@Spades-S

Description

@Spades-S

观察者模式中主体和观察者是互相感知的,发布-订阅模式是借助第三方来实现调度的,发布者和订阅者之间互不感知
image

Activity

fingerpan

fingerpan commented on Mar 1, 2019

@fingerpan
  1. 发布-订阅模式就好像报社, 邮局和个人的关系,报纸的订阅和分发是由邮局来完成的。报社只负责将报纸发送给邮局。
  2. 观察者模式就好像 个体奶农和个人的关系。奶农负责统计有多少人订了产品,所以个人都会有一个相同拿牛奶的方法。奶农有新奶了就负责调用这个方法。
1042478910

1042478910 commented on Mar 1, 2019

@1042478910

可不可以理解 为 观察者模式没中间商赚差价
发布订阅模式 有中间商赚差价

GitHdu

GitHdu commented on Mar 2, 2019

@GitHdu

观察者模式依赖一旦改变就会触发更新,而订阅发布模式则需要手动触发更新

alanchanzm

alanchanzm commented on Mar 2, 2019

@alanchanzm

联系

发布-订阅模式是观察者模式的一种变体。发布-订阅只是把一部分功能抽象成一个独立的ChangeManager。

意图

都是某个对象(subject, publisher)改变,使依赖于它的多个对象(observers, subscribers)得到通知。

区别与适用场景

总的来说,发布-订阅模式适合更复杂的场景。

在「一对多」的场景下,发布者的某次更新只想通知它的部分订阅者?

在「多对一」或者「多对多」场景下。一个订阅者依赖于多个发布者,某个发布者更新后是否需要通知订阅者?还是等所有发布者都更新完毕再通知订阅者?

这些逻辑都可以放到ChangeManager里。

fingerpan

fingerpan commented on Mar 4, 2019

@fingerpan

vue 中的 observer watcher dep 可以理解为发布订阅者模式吧?

应该是观察者模式。 vue的事件通讯机制才是发布订阅模式

rocky-191

rocky-191 commented on Mar 6, 2019

@rocky-191

vue 中的 observer watcher dep 可以理解为发布订阅者模式吧?

应该是观察者模式。 vue的事件通讯机制才是发布订阅模式

数据劫持+发布订阅

fingerpan

fingerpan commented on Mar 6, 2019

@fingerpan

vue 中的 observer watcher dep 可以理解为发布订阅者模式吧?

应该是观察者模式。 vue的事件通讯机制才是发布订阅模式

数据劫持+发布订阅

从命名上就可以区别,观察者(observer)和主题(subject)对象

qiuguixin

qiuguixin commented on Apr 20, 2019

@qiuguixin

观察者模式为一刀切模式,对所有订阅者一视同仁
发布订阅模式 可以戴有色眼镜,有一层过滤或者说暗箱操作😄

vian94

vian94 commented on May 12, 2019

@vian94
halionn

halionn commented on Jun 18, 2019

@halionn

发布-订阅增加了一个中介者,发布者和订阅着只和中介者打交到。中介者持有发布者和订阅者都引用或传入的回调,用来做订阅和通知。

xxxin128

xxxin128 commented on Jul 10, 2019

@xxxin128

观察者模式由具体目标调度,每个被订阅的目标里面都需要有对观察者的处理,会造成代码的冗余。而发布订阅模式则统一由调度中心处理,消除了发布者和订阅者之间的依赖。

monw3c

monw3c commented on Jul 11, 2019

@monw3c

低耦合和完全解藕

Hunterang

Hunterang commented on Jul 11, 2019

@Hunterang

多个发布订阅构成观察者模式,触发条件的话,感觉都是类似监听的方式,区别不明显

PatrickLh

PatrickLh commented on Jul 11, 2019

@PatrickLh

参考了Java的部分实现,观察者模式代码如下:

var subject = {
	observers: [],
	notify() {
		this.observers.forEach(observer =>{
			observer.update()
		})
	},
	attach (observer) {
		this.observers.push(observer)
	}
}
var observer = {
	update(){
		alert('updated')
	}
}
subject.attach(observer)
subject.notify()

而使用订阅发布模式,使用中间订阅发布对象的方式如下

var publisher = {
	publish(pubsub) {
		pubsub.publish()
	}
}
var pubsub = {
	subscribes: [],
	publish() {
		this.subscribes.forEach(subscribe =>{
			subscribe.update();
		})
	},
	subscribe(sub) {
		this.subscribes.push(sub)
	}
}
var subscribe = {
	update() {
		console.log('update')
	},
        subscribe(pubsub) {
            pubsub.subscribe(this);
        }
}
subscribe.subscribe(pubsub)
publisher.publish(pubsub)

自己认为,两种模式本质都是一样的,主要关键点都在于注册(添加到注册数组中)和触发(触发注册数组中的内容),只是订阅/发布模式对注册和触发进行了解耦。可以看到,使用订阅发布模式中发布者触发publish的时候,可以选择触发哪一些订阅者集合(因为publish参数传递了中间集合,可以定义多个pubsub集合),而观察者模式则只能触发所有的被观察对象。

32 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @monw3c@zhishaofei3@huangjihua@zacard-orc@PatrickLh

        Issue actions

          第 23 题:介绍下观察者模式和订阅-发布模式的区别,各自适用于什么场景 · Issue #25 · Advanced-Frontend/Daily-Interview-Question