Twlig / issuesBlog

MIT License
3 stars 0 forks source link

观察者模式和发布订阅模式的实现 #76

Open Twlig opened 2 years ago

Twlig commented 2 years ago

观察者模式: 观察者直接关注被观察者,而当被观察者更新的时候,会触发观察者里的事件。两方。观察者队列直接存在被观察者这边。

发布订阅模式: 订阅者、发布者、调度中心。三方。订阅者通过调度中心订阅事件,发布者通过调度中心发布事件。调度中心存储一个事件对象,每个事件又分别有回调函数数组,当事件被发布时,一一触发该事件回调。

观察者模式

class Fans {
    constructor(name, fn) {
        this.name = name || ''
        this.update = function(name) {
            console.log(this.name + ',看到' + name + '发新动态了!')
        }
    }
}
class Star {
    constructor(name) {
        this.name = name || ''
        this.fansSet = new Set()
    }
    addFans(fans) {
        this.fansSet.add(fans)
    }
    notify() {
        console.log(this.name + '发布了新动态')
        this.fansSet.forEach(item => item.update(this.name))
    }
}
var lili = new Fans('lili')
var xiaoming = new Fans('xiaoming')
var zzy = new Star('zzy')
zzy.addFans(lili)
zzy.addFans(xiaoming)
zzy.notify()

/*zzy发布了新动态
lili,看到zzy发新动态了!
xiaoming,看到zzy发新动态了!
*/

发布-订阅模式

class Worker {
    constructor(name, grade) {
        this.name = name || ''
        this.grade = parseInt(grade) || 0
    }
    subscribe(company, topic, fn) {
        console.log(this.name + '订阅了' + topic + '任务')
        company.subscribe(topic, fn)
    }
}
class Company {
    constructor() {
        this.topics = {}
    }
    subscribe(topic, fn) {
        if(this.topics[topic]){
            this.topics[topic].push(fn)
        }else {
            this.topics[topic] = [fn]
        }
    }
    publish(topic) {
        if(!this.topics[topic]) {
            return 
        }else {
            this.topics[topic].forEach(fn => fn())
        }
    }
}
class Boss {
    constructor(name) {
        this.name = name || ''
    }
    publish(company, topic) {
        console.log(this.name + '发布了' + topic + '任务')
        company.publish(topic)
    }
}

const companyA = new Company()
const lili = new Worker('lili', 5)
const xiaoMing = new Worker('xiaoming', 3)
const zzy = new Boss('zzy')

lili.subscribe(companyA, '做饭', function(){
    console.log('lili接收做饭任务')
})
xiaoMing.subscribe(companyA, '做饭', function(){
    console.log('xiaoming拒绝做饭任务')
})

zzy.publish(companyA, '做饭')

/*lili订阅了做饭任务
  xiaoming订阅了做饭任务
  zzy发布了做饭任务
  lili接受做饭任务
  xiaoming拒绝做饭任务
  */