js观察者模式和发布订阅模式

观察者模式(Observer Pattern)

观察者模式定义了对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯。

观察者模式类似于生活中在报社订阅报纸的现象,在一片区域内,报社是唯一的,而订阅者有很多。订阅者想要看报纸都需要去报社进行订阅,当报社生产出报纸后,会将报纸发布给所有的订阅者。

代码实现:

let Office = {
     
    list: [],
    subscribe(handler) {
     
        this.list.push(handler)
    },
    publish() {
     
        this.list.forEach(item => {
     
            item()
        })
    }
};

class User {
     
    constructor(name) {
     
        this.name = name
    }
    subscribe(handler) {
     
        console.log(`${
       this.name}订阅了报纸`);
        Office.subscribe(handler)
    }
}

let user1 = new User('张三');
let user2 = new User('李四');

user1.subscribe(function () {
     
    console.log('张三收到了报纸');
});
user2.subscribe(function () {
     
    console.log('李四收到了报纸');
});
console.log('一天后');
Office.publish();

// 输出:
// 张三订阅了报纸
// 李四订阅了报纸
// 一天后
// 张三收到了报纸
// 李四收到了报纸

发布订阅模式(Pub-Sub Pattern)

发布订阅模式是观察者模式的一种延展和优化。在发布订阅模式中,发布者和订阅者之间相互没有关联,并且对象间的关系不一定再是一对多的,也可能是多对多的。

在发布者和订阅者之间存在第三个组件,称为调度中心或消息代理,它维持着发布者和订阅者之间的联系,会将所有发布者传入的消息分发给对应的订阅者。

发布订阅模式类似生活中的商品购买现象。订阅者是顾客,发布者是供货商,而调度中心就是杂货铺。当顾客去杂货铺购买商品,如果商品断货了,就可以在杂货铺订阅这个商品,并给出对这个商品的条件。当杂货铺收到供货商提供的商品后,便可以告知顾客。这一过程中,供货商和顾客不存在任何联系,并且供货商和顾客都可以存在多个。

代码实现:

let Store = {
     
    handlers: {
     },
    subscribe(type, handler) {
     
        if (!this.handlers[type]) {
     
            this.handlers[type] = []
        }
        this.handlers[type].push(handler)
    },
    publish(type, ...args) {
     
        if (!this.handlers[type]) {
     
            return new Error('未注册该事件')
        }
        this.handlers[type].forEach(handler => {
     
            handler(...args)
        })
    }
};

class Customer {
     
    constructor(name) {
     
        this.name = name
    }
    subscribe(type, handler) {
     
        console.log(`${
       this.name}订阅了${
       type}`);
        Store.subscribe(type, handler)
    }
}

class Supplier {
     
    constructor(name) {
     
        this.name = name
    }
    publish(type, args) {
     
        console.log(`${
       this.name}发布了${
       type}`);
        Store.publish(type, args)
    }
}

let customer1 = new Customer('张三');
let customer2 = new Customer('李四');
let supplier1 = new Supplier('供应商1');
let supplier2 = new Supplier('供应商2');

customer1.subscribe('衣服', function (size) {
     
    if (size > 10) console.log('张三说:衣服太大了,我不要');
    else console.log('张三说:我可以接受');
})
customer2.subscribe('衣服', function (size) {
     
    if (size < 20) console.log('李四说:我可以接受');
    else console.log('李四说:衣服太大了,我不要');
})
customer2.subscribe('裤子', function (size) {
     
    if (size > 10) console.log('李四说:裤子太大了,我不要');
    else console.log('李四说:我可以接受');
})

supplier1.publish('衣服', 15)
supplier2.publish('裤子', 15)

// 输出:
// 张三订阅了衣服
// 李四订阅了衣服
// 李四订阅了裤子
// 供应商1发布了衣服
// 张三说:衣服太大了,我不要
// 李四说:我可以接受
// 供应商2发布了裤子
// 李四说:裤子太大了,我不要

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

js观察者模式和发布订阅模式_第1张图片
观察者模式: 观察者(Observer)直接订阅(Subscribe)主题(Subject),而当主题被激活的时候,会触发(Fire Event)观察者里的事件。

发布订阅模式: 订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Topic),当发布者(Publisher)发布该事件(Publish topic)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。

区别: 在观察者模式中,发布者和订阅者是一对多的关系,并且是紧密关联的。在发布订阅模式中,通过调度中心实现了发布者和订阅者的解耦,将事件集中放到调度中心进行处理。

你可能感兴趣的:(设计模式,javascript,vue.js)