发布订阅模式又叫做观察者模式

最近看到很多文章分析发布订阅模式和观察者模式的异同,其实在大多关于设计模式的书籍里面都认为二者是一样的。

发布订阅模式,又叫做观察者模式,又叫做消息机制,它定义对象间的一种一对多的依赖关系,当一个对象状态改变的时候,所有依赖于它对象都将得到通知.

个人感觉他们俩也是一样的,只不过是写法不同,理解的切入角度不同造成他们好像是两种设计模式。

  1. 最简单的发布订阅模式
	const eventCenter = {
    	// 调度中心
    	list: [],
    	// 订阅
    	on(fn){
        	this.list.push(fn)
    	},
    	// 发布
    	emit(){
        	this.list.forEach(fn => {
            	fn()
        	});
    	}
	}
	eventCenter.on(()=>{console.log('A订阅了')})
	eventCenter.on(()=>{console.log('B订阅了')})
	eventCenter.emit() // A订阅了  B订阅了
把调用eventCenter.on的对象叫做订阅者
把调用eventCenter.emit的对象叫做发布者
订阅者和发布者通过一个eventCenter完成了解耦
  1. 带着面向对象的思维来写
	// 定义被观察者
	function BeObserve() {
    	this.observeList = []
    	this.add = function(observe){
        	this.observeList.push(observe)
    	}
    	this.notify = function(){
        	this.observeList.forEach((observe)=>{
            	observe.update()
        	})
    	}
	}
	// 定义观察者
	function Observe(change) {
    	this.update = function(){
        	console.log(change)
    	}
	}

	const beObserve = new BeObserve()
	const observe1 = new Observe('界面温度+1')
	const observe2 = new Observe('界面湿度+11')
	const observe3 = new Observe('风力增加+11')
	beObserve.add(observe1)
	beObserve.add(observe2)
	beObserve.add(observe3)
	beObserve.notify()
beObserve称作被观察者
observe1,observe2,observe3称作观察者
二者对比

对比1中来看可以把observe1,observe2,observe3叫做订阅者
把调用beObserve.notify()的对象叫做 发布者。原理都是,订阅者通过调用on/add完成订阅,发布者通过调用emit/notify通知所有订阅者。订阅者和发布者通过eventCenter/beObserve松耦合。

总结
将调用调用on/add的称作订阅者;将调用emit/notify称作发布者;这么来看二者就完全相同了

最后来张流传慎广的差异图(修订版)

在这里插入图片描述
实现一个通用的发布订阅模式

const eventCenter = (function(){
    let eventList = {}, on, emit, off, once;
    on = function(type, fn){
        if (!eventList[type]) {
            eventList[type] = []
        }
        eventList[type].push(fn)
    }
    emit = function(){
        const [type, ...args] = arguments
        const fns = eventList[type]
        if (!fns || fns.length === 0) {
            return false
        }
        fns.forEach(fn => {
            fn.apply(this, args)
        });
    }
    off = function(type, fn){
        const fns = eventList[type]
        if (!fns || fns.length === 0) {
            return false
        }
        eventList[type] = fns.filter((item)=>{
            console.log(item[fn], 'item')
            console.log(fn, 'fn')
            console.log(fn !== item.fn, 'boolean')
            // fn !== item[fn] hack once订阅的事件不触发不能取消订阅BUG
            return fn !== item && fn !== item.fn
        })
        console.log(eventList[type].toString(), 'eventList[type]')
    }
    once = function(type, fn){
        function one(){
            off(type, one)
            fn.apply(this, arguments)
        }
        one.fn = fn  // hack once订阅的事件不触发不能取消订阅BUG
        on(type, one)
    }
    return {on,emit,off,once}
})()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值