觀察者模式
觀察者模式又被稱為發布-訂閱模式,使用一個對象來收集訂閱者,在發布時遍歷所有訂閱者,然后將信息傳遞給訂閱者,可以這樣來實現一個簡單的模式
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 = resultthis.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回答問題*/
結論
通過觀察者模式可以團隊開發中模塊間通訊問題
解耦兩個相互依賴的對象,使其側重依賴于觀察者的消息機制。這樣對于任意一個訂閱者對象來說,其他訂閱者對象的改變不會影響到自身。對于每一個訂閱者來說,其自與既可以是消息的發出者也可以是消息的執行者,這都依賴于調用觀察者對象的三種方法(訂消息,注銷消息,發布消息)中的哪一種