JS-设计模式之观察者模式

最近在学习vue的双响数据绑定时,发现使用到观察者模式,但是我对于这种设计模式一知半解,所以特意总结下来。

基本定义

观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。

观察者:

(Watcher)将自己注册到被观察对象(Dep)中,被观察对象将观察者存放在一个容器(Container)里。

被观察者:

被观察对象发生了某种变化,从容器中得到所有注册过的观察者,将变化通知观察者。

实现方式

观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。

代码示例

// 被观察者
function Dep () {
    //存放观察者的容器
    this.watchers = [];
    let state = '';

    // 获取
    this.getState = function () {
        return state;
    };

    // 设置
    this.setState = function (value) {
        if (state === value) {
            return;
        }
        state = value;
        // state变化时,发出通知
        this.notice();
    };
}

//添加观察者
Dep.prototype.addWatcher = function (watcher) {
    let flag = false;
    this.watchers.forEach(item => {
        if (item === watcher) {
            flag = true;
        }
    });
    if (!flag) {
        this.watchers.push(watcher);
    }
}
// 删除观察者
Dep.prototype.removeWatcher = function (watcher) {
    let _this = this;
    _this.watchers.forEach((item,index) => {
        if (item === watcher) {
            _this.watchers.splice(index, 1);
        }
    });
}
//发出通知
Dep.prototype.notice = function () {
    let _this = this;
    _this.watchers.forEach(item => {
        //观察者容器中,每一个观察者都会执行update方法
        item.update(_this.getState());
    });
}

// 观察者
function Watcher (name) {
    this.name = name;
    // 当被观察者的值改变时(setState()执行),观察者对象执行update方法
    this.update = function (data) {
        // do something
        console.log(this.name + '接收到通知了:' + data);
    }
}

// 创建被观察者实例对象
let dep = new Dep();
// 创建观察者实例对象, 2个
let watcher_a = new Watcher('a');
let watcher_b = new Watcher('b');

// 将观察者对象添加到被观察者的容器中
dep.addWatcher(watcher_a);
dep.addWatcher(watcher_b);

// 被观察者对象的值发生变化
dep.setState(1);
//输出结果:
//a接收到通知了:1
//b接收到通知了:1

参考资料

《javascript 设计模式》
JavaScript设计模式之观察者模式(学习笔记)

猜你喜欢

转载自blog.csdn.net/zhq2005095/article/details/78476904
今日推荐