订阅发布与观察者模式

104 阅读2分钟

这两天常被人问到你知道什么是观察者模式吗? 什么是订阅发布模式? 两者又有什么区别?我细细一想,还真是被问到了,脑子里开始绕了起来。

借着这个疑问,就又复习了一下。

订阅发布模式

个人理解, 订阅发布模式其实就是像我们去报亭里订阅一份报纸,或者是在微信上订阅公众号,就是我通过报亭订阅了这个事件,然后一旦有这个事件的时

候,报亭呢,就会发布,我就会收到这个事件了。报亭---就是订阅发布的中间人。这个是和观察者模式最大的区别。多说无益,代码来展示一下。

var pubsub = (() => {
    var events = {};
    function subscripe(eventName, fn) {
        if (!events[eventName]) {
            events[eventName] = []
        }
        events[eventName] = fn;
    }
    function publish(eventName, ...args) {
        if (!events[eventName]) {
            // 说明没有订阅这个事件
            return;
        }
        for (let fn of  events[eventName]) {
            fn(...args);
        }
    }
    return {
        subscripe,
        publish
    }
})()

// 使用
pubsub.subscribe('aa', (name, age) => {
   console.log(`I am ${name}, my age is ${age}`)
})
pubsub.publish('aa', 'zj', 20)
// => I am zj, my age is 20;
// 因为事件一发布,订阅事件就收到了,然后执行了打印方法。

观察者模式

比如我家里有一个摄像头,然后家人都有权限查看。 那么家人就是观察者, 家里的情况是被观察者。 这个就是一个直接的一对多关系。 直接进行观察的。

就好比是拍卖一个东西, 好多人都在看着,那么这个东西是被观察者, 在座的参加拍卖的都是观察者。 再举个例子,比如直播间。 主播是被观察者,

观众是观察者。 那么主播说了什么的时候, 观察者一直在观察者, 主播提到谁的名字,所有观察者都可以看到。

// 举个例子,subject 比如是主播
class Subject {
    constructor() {
        this.name = '';
        this.people = [];
    }
    attatch(person) {
        this.people.push(person);
    }
    getName() {
        return this.name;
    }
    setName(name) {
        this.name = name;
        this.notifyAll();
    }
    notifyAll() {
        this.people.forEach((person) => {
            person.update();
        })
    }
}
class Observer {
    constructor(name, subject) {
        this.name = name;
        this.subject = subject;
        this.subject.attatch(this);
    }
    update() {
        console.log(`${this.name} heard ${this.subject.getName()}`)
    }
}

var s = new Subject()
var a1 = new Observer('a1', s)
var a2 = new Observer('a2', s)
s.setName('zj')

二者区别

  1. 订阅发布可以通过一个中间人来完成, 观察者模式时观察者和被观察者直接沟通来完成。

  2. 订阅发布是通过中间人来订阅一个事件,如果有这个事件的话,则发布后,订阅人就会执行。 而观察者模式不同,只要是观察者,那么被观察者一有

动静,所有的观察者都会得到更新。