概述

观察者模式是基于发布订阅的一种模式,发布订阅的特点是绑定的和发布的两者不存在关系, 是靠一个统一的事件调度来实现的,也就是发布和订阅是不存在关系的。

但是观察者模式就不太一样了,他的特点是需要有观察者,还要有被观察者,被观察者要放在观察者的里面,比如说有一个小宝宝,要观察这个小宝宝的父母是观察者,这个小宝宝就是被观察者,观察者和被观察者之间是有关系的。

在vue中的双向数据绑定就是依靠观察者模式实现的,相当于我们要建立一个watch,当数据变化的时候,每一个观察者都要刷新数据。

这里我们写一个小例子,观察者模式还是比较重要的,首先要有观察者和被观察者,被观察者要存放在观察者中,被观察者要提供一个更新的方法,当观察者的数据发生变化时,需要执行被观察者的更新方法。

首先我们有一个观察者Subject, 被观察者Observer,被观察者里面要有个状态,观察者存在一个更新的方法。当被观察者状态发生变化时,会通知观察者,也就是调用观察者的更新方法。

function Observer() {
    this.status = "状态1";
    this.arr = [];
}

functuon Subject() {

}
Subject.prototype.update = function() {

}

被观察者需要提供一个attach方法, 方便观察者注册,以实现观察者的通知事件,在观察者的内部存在一个数组,存储所有的观察者对象。每次attach被调用的时候,我们需要将获取到的观察者对象存储到数组中。

我们还需要给Observer增加一个设置状态的方法setStatus, 在这个方法里面更新status状态,还要通知所有的观察者,执行观察者的update方法。传递新的状态值。

function Observer() {
    this.status = "状态1";
    this.arr = [];
}
Object.prototype.attach = function(s) {
    this.arr.push(s);
}
Object.prototype.setStatus = function(status) {
    this.status = status;
    this.arr.forEach(function (subject) {
        subject.update(status);
    })
}

观察者对象在创建时会传递一个名字和要观察的对象,所以需要接收两个参数。name和target, 这样在每次更新的时候我们就可以发现是那个被观察者发生了状态变化。

functuon Subject(name, target) {
    this.name = name;
    this.target = target;
}
Subject.prototype.update = function(status) {
    console.log(this.name, status);
}

我们这里会把观察者存放在被观察者中,每次被观察者状态发生变化,都会通知所有观察者状态更新。

function Observer() {
    this.status = "状态1";
    this.arr = [];
}
Object.prototype.attach = function(s) {
    this.arr.push(s);
}
Object.prototype.setStatus = function(status) {
    this.status = status;
    this.arr.forEach(function (subject) {
        subject.update(status);
    })
}

functuon Subject(name, target) {
    this.name = name;
    this.target = target;
}
Subject.prototype.update = function(status) {
    console.log(this.name, status);
}

var o = new Observer();

var s1 = new Subject('s1', o);
o.attach(s1);

var s2 = new Subject('s2', o);
o.attach(s2);

o.setStatus('状态2');

o.setStatus('状态3');