js设计模式-观察者模式与发布订阅模式

1、观察者模式

这里我们通过老师和学生两个实体来进行构建对象模拟,简单来说这个案例和群发消息大致差不多

我们首先构建两个类对象,第一个学生对象只需要加一个接收消息的方法,之后主要代码还是在老师类当中,我们需要通过一个方法将需要接收消息的实体对象加入进来,这也是addObServer方法的含义,并且添加一个发送消息的方法,我们只需要遍历刚才加进来的对象,将需要发送的消息作为参数,因为obServer数组里面存的都是学生类,我们只需要调用学生类接收消息的方法就实现了观察者模式。

class Student {
          
   
    constructor(name) {
          
   
        this.name = name
    }
    notice(msg) {
          
   
        console.log(this.name + "收到了消息,消息是:" + msg)
    }
}


class Teacher{
          
   

    constructor(){
          
   
        this.obServer = []
    }

    addObServer(ob){
          
   
        this.obServer.push(ob)
        return this
    }

    sendMsg(msg){
          
   
        this.obServer.forEach(item=>{
          
   item.notice(msg)})
    }
}

const Chen = new Teacher()
const ZhangSan = new Student("张三")
const LiSi = new Student("李四")
const WangWu = new Student("王五")
Chen.addObServer(ZhangSan).addObServer(LiSi).addObServer(WangWu)

Chen.sendMsg("这是刘老师发布的消息,===== >>>>> ")

2、发布订阅模式

在对于现在前端框架的崛起,大家对发布订阅这几个字也很熟悉了,像Vue用到的VueX以及React框架用的Pubsub都是发布订阅模式,简单来说,我们只需要在一个地方通知(发布)修改一个变量、对象的值,而在另一个地方进行订阅该变量、对象就可以获取到改变之后的值。

在这里,定义一个消息管理类,提供两个方法,一个用于订阅(on)一个用来发布(emit),在订阅当中也就是on方法,on方法接收两个参数,第一个是消息名称,表示只订阅哪个消息名称的消息,第二个为一个回调函数,当消息对象当中有这个消息名称,就将该回调加入到对应的消息名称下,反之直接将该回调塞给该消息名称下,而在发布时,我们只需要执行向哪个消息名称进行发布,并且携带发布内容,而emit方法接收参数后,对消息对象的消息名称之后逐个回调执行,也就是会调用由on方法塞进来的回调函数,这样当emit发布消息之后,对应的on方法就可以拿到最新发布的消息值了。

class Messager {
          
   
    message = {
          
   }
    on(msgName, callback) {
          
   
        if (this.message[msgName]) {
          
   
            this.message[msgName].push(callback)
        } else {
          
   
            this.message[msgName] = [callback]
        }
    }
    emit(msgName, ...params) {
          
   
        console.log(msgName, this.message)
        if (this.message[msgName]) {
          
   
            this.message[msgName].forEach(callback => {
          
   
                callback.call(this, ...params)
            })
        }
    }
}

let messager = new Messager()

messager.on(Chen, (msg) => {
          
   
    console.log("张三收到消息 ====>>>> " + msg)
})

messager.on(Chen, (msg) => {
          
   
    console.log("李四收到消息 ====>>>> " + msg)
})


messager.on(Chen, (msg) => {
          
   
    console.log("王五收到消息 ====>>>> " + msg)
})

setTimeout(() => {
          
   
    messager.emit("Chen", " <<<<=== 这是陈发布的消息 ===>>>> ")
}, 3000)
经验分享 程序员 微信小程序 职场和发展