JavaScript中的观察者模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Picking_up_stones/article/details/76273481

前言:在各种设计模式中,观察者模式具有很重要的应用,比如前端很流行的框架Vue.js就是基于观察者模式实现的,最近也了解了下观察者模式的实现原理,简单的说就是一个对象改变了,观察者察觉到了这种改变,它将这种改变通知给所有和这个对象有关的函数,然后这些函数被调用并执行。


一. 观察者模式的实现原理

如前言中所说,观察者具有观察和通知的职责,那么它是如何来实现这两个职责的呢?

所谓观察和通知,就是一旦数据变化就立马发起关于这个数据改变的通知,那么问题又来了,通知给谁看呢?聪明的你肯定一下子就想到了,当然是给关心这个数据变化的某某看了,某某收到通知后就可以去发表自己的见解了。所以我们可以这样理解:

(1)要想把改变通知出去,必须要有相应的通知的方法;

(2)通知发布出去,得有人看,每个人都是一个订阅者,所以必须得有添加订阅者的方法;

(3)订阅之后又不感兴趣了,就可以取消订阅,所以又有了一个取消订阅的方法。

实现代码:

var observer = {
    //添加订阅者
    addSubscriber: function (callback) {
        this.subscribers[this.subscribers.length] = callback;
    },
    //移除订阅者
    removeSubscriber: function (callback) {
        for (var i = 0; i < this.subscribers.length; i++) {
            if (this.subscribers[i] === callback) {
                delete (this.subscribers[i]);  //删除某个订阅者
            }
        }
    },
    //发布通知
    publish: function (data) {
        for (var i = 0; i < this.subscribers.length; i++) {
            if (typeof this.subscribers[i] === 'function') {
                this.subscribers[i](data); //执行和data相关的操作
            }
        }
    }
};

我们可以看到在观察者的内部有个订阅者的数组,关于添加、删除、通知都是针对这个数组来操作的,每个订阅者都执行的是和data相关的操作,即只要data改变,每个订阅者的方法都会被调用。

二. 代码演示

上面的代码主要讲的是观察者如何实现,下面来看下如何订阅、发布、删除:
(1)创建一个观察者:

function CreateObserver(){
    var obj = {};
    for (var i in observer){
        obj[i] = observer[i];
    }
    obj.subscribers = [];  //添加一个订阅者数组
    return obj;
}
var weather = CreateObserver();

(2)添加订阅:

如上面我们创建了一个叫做天气的观察者,最近西安的温度40+,天气想知道人们的感受,所以就发布了一条关于天气的帖子,并订阅了形形色色的关于他的评价:

var someWords = ['北郊说:下雨之后,从红烧变清蒸!', '西安人民说:我与铁板烧之前只差一撮孜然!', '非洲同胞说:欢迎来非洲避暑!', '吐鲁番说:地表温度67,我终于不是第一了,哈哈哈。。。'];

var func = [];

for (let i = 0; i < someWords.length; i++){
    func[i] = function (title){
        console.log(title + "---" +someWords[i]);
    }
    weather.addSubscriber(func[i]);
}

weather.publish('西安地表温度67,全国第一!热热热');

输出如下:

这里写图片描述

只想说一句,是真的热!!!!

(3)取消订阅

天气觉得吐鲁番堕落了,不是第一还这么开心,我要取消对他的订阅:

weather.removeSubscriber(func[3]);

weather.publish('西安地表温度67,全国第一!热热热');

所以输出就这样了:

这里写图片描述


以上是本人对观察者模式的理解,我觉得它的实现巧妙的地方在于在内部维护了一个数组,这个数组是关于某个数据变化后的所有回调函数,当数据变化后逐一去执行这些回调函数,既可以去统一管理数组成员,又可以让数组成员去干自己的事情。

猜你喜欢

转载自blog.csdn.net/Picking_up_stones/article/details/76273481