一、觀察者模式
觀察者模式 :對(duì)象間存在一對(duì)多的依賴(lài)關(guān)系伞访,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變乌奇,會(huì)讓所有依賴(lài)它的對(duì)象得到通知并被自動(dòng)更新没讲,這種模式就是觀察者模式。
模式動(dòng)機(jī):一個(gè)觀察目標(biāo)可以對(duì)應(yīng)多個(gè)觀察者礁苗,而且這些觀察者之間沒(méi)有相互聯(lián)系爬凑,可以根據(jù)需要增加和刪除觀察者,使得系統(tǒng)更易于擴(kuò)展试伙,這就是觀察者模式的模式動(dòng)機(jī)嘁信。
解決的問(wèn)題:一個(gè)對(duì)象改變需要通知所有依賴(lài)它的對(duì)象去改變。
優(yōu)點(diǎn):1.解耦疏叨。
2.支持廣播通信潘靖。
缺點(diǎn): 1.觀察者太多影響性能。
2.觀察者被觀察者有循環(huán)依賴(lài)蚤蔓,觀察目標(biāo)會(huì)觸發(fā)循環(huán)調(diào)用卦溢,可能導(dǎo)致系統(tǒng)崩潰。
3.觀察者只知道目標(biāo)變化秀又,不知道目標(biāo)是怎么變化单寂。
二、js實(shí)現(xiàn)一個(gè)觀察者模式
// 1.定義一個(gè)觀察類(lèi)
function Pubsub(){
//存放事件
this.handles = {}
}
Pubsub.prototype = {
// 2.實(shí)現(xiàn)事件訂閱on
on:function(type,handle){ //type=>事件類(lèi)型 handles=>事件
if(!this.handles[type]){
this.handles[type] = []
}
this.handles[type].push(handle)
},
// 3.注冊(cè)觸發(fā)事件
emit:function(){
const type = Array.prototype.shift.call(arguments) // shift 獲取傳入?yún)?shù)的第一個(gè)
const handleArray = this.handles[type]
if(!handleArray) return
for(let i = 0;i<handleArray.length;i++){
const handleItem = handleArray[i]
handleItem.apply(this,arguments)
}
},
// 4.注冊(cè)解除監(jiān)聽(tīng)事件
remove:function(type,handle){
const handlesArray = this.handles[type]
if(handlesArray){
if(!handle){
handlesArray = [] // 清空數(shù)組
}
}else {
for(let i =0;i<handlesArray.length;i++){
const _handle = handlesArray[i]
if(_handle === handle){ // 事件匹配就刪掉
handlesArray.splice(i,1)
}
}
}
}
}
// 調(diào)用
const observer1 = new Pubsub()
const fn = function(val){console.log('我被點(diǎn)擊了' + val + '次')}
observer1.on('click',fn) //注冊(cè)
observer1.emit('click','1') //觸發(fā)
observer1.emit('click','2') // 觸發(fā)
observer1.remove('click',fn) // 解除