觀察者模式與發佈訂閱模式(簡易版)

網上的大部分例子有些太官方,說實在的有點很差理解,說下我的粗淺看法javascript

觀察者模式

這是一個女神和備胎們的故事java

class Girl {
    constructor() {
        this.backupList = [] // 備胎列表
    }
    add(person) {  // 加入備胎
        this.backupList.push(person)
    }
    remove(person) {  // 踢出備胎
        let index = this.backupList.findIndex(item=>item===person)
        index > -1 && this.backupList.splice(index,1)
    }
    sendMsg(msg) {  // 給備胎髮消息
        for(let o of this.backupList) {
            o.update(msg)
        }
    }
}
class Person {
    constructor(name) {
        this.name = name  // 備胎的名字
    }
    update(msg) {
        // 備胎收到女神的消息
        console.log(`我是${this.name},女神給我說:${msg}`)
    }
}
let lisa = new Girl()
let person1 = new Person('阿天')
let person2 = new Person('阿狗')
lisa.add(person1)
lisa.add(person2)
lisa.sendMsg('我想有個家')

女神Lisa的角色就是一個「觀察者」,她發現她中獎了,因此發了消息給備胎們this

優勢: 一對多,下降耦合

發佈訂閱模式

這是一個相親機構的故事code

let agent = {
    list: {}, // 訂閱者容器
    on(key, fn) { // 添加訂閱者
        if(!this.list[key])this.list[key] = []
        this.list[key].push(fn)
    },
    off(key,fn){ // 移除訂閱者
        let fnList = this.list[key]
        if(!fnList)return
        if(!fn) { // 若是沒有具體的訂閱者,則移除所有
            fnList.length = 0
        }else {
            fnList.forEach((item,index) => {
                item === fn && fnList.splice(index,1)
            })
        }
    },
    trigger(key, ...args) { // 發佈
        for(let fn of this.list[key])fn.call(this,...args)
    }
}
知識點: 此時出現了「字面量模式」

此時有兩位男士訂閱了該機構,關鍵詞分別是「年輕」和「好身材」事件

agent.on('young',info=>{
    console.log(`有一個新發布:姓名:${info.name},年齡:${info.age}`)
})
agent.on('body',info=>{
    console.log(`有一個新發布:姓名:${info.name},胸圍:${info.bust}`)
})

又有兩位女士來到該機構發佈了她們的信息ip

agent.trigger('young',{
    name: '圓圓',
    age: '18'
})
agent.trigger('body',{
    name: '希希',
    bust: '88'
})

同時,兩位訂閱的男士就收到了發佈的信息rem

有一個新發布:姓名:圓圓,年齡:18
有一個新發布:姓名:希希,胸圍:88
優勢: 多對多,耦合更低
on,off,trigger不就是Jquery中綁定事件嘛,因此它就是典型的發佈訂閱模式

區別

發佈訂閱模式比觀察者模式多了一箇中間層,耦合更低,項目越大,優點就更明顯,並且這個中間層還能提取出來做爲一個單獨的文件寫各類操做it

相關文章
相關標籤/搜索