js 观察者

观察者模式模式简介

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知全部的观察者对象,使他们可以自动更新本身。

观察者模式机动

创建一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其余对象,其余对象将相应作出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标能够对应多个观察者,并且这些观察者之间没有相互联系,能够根据须要增长和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。

生活中的观察者模式

如今年轻人都喜欢玩手机,好比我本身我是比较爱看直播,每一个直播间都有一个订阅的按钮,若是你喜欢这个直播你就会订阅一下它,可是每一个主播开播的时间是不固定的,咱们不能一直盯着直播间看吧,这样很浪费时间也错过了其余的内容,因此你订阅它以后,每一个主播开播都会向本身订阅的号发布本身开播的消息

代码分析

  1. 咱们使用Es6先建立一个class
// 发布订阅实现
    class Observer {
        constructor () {
        }
    }
  1. 订阅(subscribe)的函数callback参数用做传入的订阅者回调函数,this.subscribers.length插入当前本身应当的位置
subscribe (callback) {
        // 将传入的函数赋予这个数组
        this.subscribers[this.subscribers.length] = callback
    }
  1. 退订(retreatSubscribe)函数,传入退订者的回调函数,循环存储订阅者的数组this.subscribers,根据传入的退订者和订阅者数组中对比,相同者删除订阅者
retreatSubscribe (callback) {
        for(var i = 0;i < this.subscribers.length;i++) {
            if(this.subscribers[i] === callback){
                delete (this.subscribers[i])
            }
        }
    }
  1. 观察(publish)函数,观察订阅者的动做,this指向的是这个class Observer,将Observer内的函数方法赋予订阅者对象,声明数组用做存储订阅者回调函数
make (o) {
        // this === Observer这个对象的函数
        for(var i in this){
            // this[i]Observer对象里面的每一个方法
            o[i] = this[i]
            // 声明数组用做存储订阅者回调函数
            o.subscribers = []
        }
    }
  1. 发布(publish)函数,循环存储订阅者回调函数的数组,检测是否为函数,若是是函数进行发布消息
//发布
    publish (what) {
        for(var i = 0;i< this.subscribers.length;i++){
            if(typeof this.subscribers[i] === 'function'){
                // add函数
                this.subscribers[i](what)
            }
        }
    }

代码组合起来

下面的class代码是我将上面步骤的组合到一块儿的一系列代码,由订阅对象,观察对象,发布消息,退订组成的观察者模式,也叫发布订阅
class Observer {
        constructor () {}
        // 订阅
        subscribe (callback) {
            // 将传入的函数赋予这个数组
            this.subscribers[this.subscribers.length] = callback
        }
        // 退订
        retreatSubscribe (callback) {
            for(var i = 0;i < this.subscribers.length;i++) {
                if(this.subscribers[i] === callback){
                    delete (this.subscribers[i])
                }
            }
        }
        // 观察对象
        make (o) {
            // this === Observer这个对象的函数
            for(var i in this){
                // this[i]Observer对象里面的每一个方法
                o[i] = this[i]
                // 声明数组用做存储订阅者回调函数
                o.subscribers = []
            }
        }
        // 发布
        publish (what) {
            for(var i = 0;i< this.subscribers.length;i++){
                if(typeof this.subscribers[i] === 'function'){
                    // add函数
                    this.subscribers[i](what)
                }
            }
        }
    }

使用上面的观察者

1.咱们必须建立一个订阅者对象
let people = {
}
2.咱们观察这个对象而且赋值给这个对象可使用的功能,咱们让他能够行动,能够作出行为举止
Observer.make(people)
3.声明想发布的信息代码
let wanglei = {
        add (what) {
            console.log('wanglei给' + what);
        }
    }
4.咱们订阅一下想要发送的函数,咱们这里正好是声明的函数,用来订阅用的,能够回顾上面订阅的函数代码
Observer.subscribe(wanglei.add)
5.发布消息咱们将qaaa字符传递到add订阅函数的what形参里面用来组合发送消息
Observer.publish('qaaa')
 
 //打印
  wanglei给qaaa
6.退订既然能够订阅,咱们就能够退订,退订主要走的retreatSubscribe函数,咱们将订阅者的信息传递到退订函数就能够删除这个订阅者,以后再发布就没法再接收到相关信息
Observer.retreatSubscribe(wang.add)

观察者优缺点

那么使用完观察者以后大家有什么感触,总的来讲观察者有优势也有缺点,每一个事物都同样总会有优缺点,可是观察者的优势在咱们部分功能中起到不少做用,咱们看看它的优缺点
优势:
1. 支持简单的广播通讯,自动通知全部已经订阅过的对象
  
2. 目标对象与观察者存在的是动态关联,增长了灵活性

3. 目标对象与观察者之间的抽象耦合关系可以单独扩展以及重用
缺点:
1. 若是一个观察目标对象有不少直接和间接的观察者的话,将全部的观察者都通知到会花费不少时间

2. 若是在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能致使系统崩溃

3. 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化
最后咱们的观察者就到这里了
相关文章
相关标签/搜索