观察者模式又被称为发布-订阅模式,使用一个对象来收集订阅者,在发布时遍历所有订阅者,然后将信息传递给订阅者,可以这样来实现一个简单的模式
- const Observable = (function () {
- let __messages = {}
- return {
- register: function (type, fn) {
- if (typeof __messages[type] === 'undefined') {
- __messages[type] = [fn]
- } else {
- __messages[type].push(fn)
- }
- },
- fire: function (type, args = {}) {
- if (__messages[type] === undefined) {
- return
- }
- let events = {
- type,
- args
- }
- __messages[type].forEach(fn => {
- fn.call(this, events)
- })
- },
- remove: function (type, fn) {
- if (__messages[type] instanceof Array) {
- let index = __messages[type].indexOf(fn)
- if (index >= 0) {
- __messages[type].splice(index, 1)
- }
- }
- }
- }
- })()
-
- const fn = function (e) {
- console.log(e.type,e.args.msg)
- }
- Observable.register('test', fn)
- Observable.remove('test',fn)
- Observable.register('test', function (e) {
- console.log(e.type,e.args.msg,2122)
- })
-
- Observable.fire('test', { msg: 'hello world' }) // test hello world 2122
假使有一个学生跟老师的互动
-
- // 学生类
- const Student = function (result) {
- this.result = result
- this.say = ()=> {
- console.log(this.result)
- }
- }
-
- // 学生回答问题
- Student.prototype.answer = function (que) {
- // 注册事件
- Observable.register(que, this.say)
- }
-
- Student.prototype.sleep = function (que) {
- console.log(this.result + ' ' + que + '被注销')
- Observable.remove(que, this.say)
- }
-
- // 老师类
- const Teacher = function () {
- }
- Teacher.prototype.ask = function (que) {
- console.log('老师提问:' + que)
- Observable.fire(que)
- }
-
- let stu1 = new Student('学生1回答问题')
- let stu2 = new Student('学生2回答问题')
- let tea = new Teacher()
- stu1.answer('1+1等于多少')
- stu1.answer('2+2等于多少')
- stu2.answer('1+1等于多少')
- stu2.answer('2+2等于多少')
- stu2.sleep('1+1等于多少')
- tea.ask('1+1等于多少')
- tea.ask('2+2等于多少')
- /*
- 学生2回答问题 1+1等于多少被注销
- 老师提问:1+1等于多少
- 学生1回答问题
- 老师提问:2+2等于多少
- 学生1回答问题
- 学生2回答问题
- */
通过观察者模式可以团队开发中模块间通讯问题
解耦两个相互依赖的对象,使其侧重依赖于观察者的消息机制。这样对于任意一个订阅者对象来说,其他订阅者对象的改变不会影响到自身。对于每一个订阅者来说,其自与既可以是消息的发出者也可以是消息的执行者,这都依赖于调用观察者对象的三种方法(订消息,注销消息,发布消息)中的哪一种