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

发布订阅模式

发布订阅模式又叫观察者模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。

这是一种创建松散耦合代码的技术。它定义对象间 一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。由主体和观察者组成,主体负责发布事件,同时观察者通过订阅这些事件来观察该主体。主体并不知道观察者的任何事情,观察者知道主体并能注册事件的回调函数。

观察者模式中有主题(Subject)和观察者(Observer),分别对应报社和订阅用户(你).观察者模式定义了对象之间的一对多的依赖关系,这样,当”一”的一方状态发生变化时,它所依赖的”多”的一方都会收到通知并且自动更新.如图:

《js设计模式 --- 发布订阅模式(观察者模式)》

实现

var Event = {
    // 通过on接口监听事件eventName
    // 如果事件eventName被触发,则执行callback回调函数
    on: function (eventName, callback) {
        //我的代码
        if(!this.handles){
            //this.handles={};
            Object.defineProperty(this, "handles", {
                value: {},
                enumerable: false,
                configurable: true,
                writable: true
            })   
        }      
       if(!this.handles[eventName]){
            this.handles[eventName]=[];
       }
       this.handles[eventName].push(callback);
    },
    // 触发事件 eventName
    emit: function (eventName) {
        //你的代码
       if(this.handles[arguments[0]]){
           for(var i=0;i<this.handles[arguments[0]].length;i++){
               this.handles[arguments[0]][i](arguments[1]);
           }
       }
    }
};

或者

var eve = function () {
            // 通过on接口监听事件eventName
        // 如果事件eventName被触发,则执行callback回调函数
    this.on = function (eventName, callback) {
        //我的代码
        if(!this.handles){
            //this.handles={};
            Object.defineProperty(this, "handles", {
                value: {},
                enumerable: false,
                configurable: true,
                writable: true
            })   
        }      
        if(!this.handles[eventName]){
            this.handles[eventName]=[];
        }
        this.handles[eventName].push(callback);
    };
        // 触发事件 eventName
    this.emit = function (eventName) {
        //你的代码
        if(this.handles[arguments[0]]){
            for(var i=0;i<this.handles[arguments[0]].length;i++){
                this.handles[arguments[0]][i](arguments[1]);
            }
        }
    };
};

测试

//var Event = new eve(); //第二种函数类型
Event.on('test', function (result) {
    console.log(result);
});
Event.on('test', function () {
    console.log('test');
});
Event.emit('test', 'hello world'); // 输出 'hello world' 和 'test'

var person1 = {};
var person2 = {};
Object.assign(person1, Event);
console.log(person1);
console.log(person2);
console.log('ssssssssssssssssssssssss');

Object.assign(person2, Event);

console.log(person1);
console.log(person2);
console.log('aaaaaaaaaaaa');

person1.on('call1', function () {
    console.log('person1');
});

console.log(person1);
console.log(person2);
console.log('bbbbbbbbbbbbbbbbbbbbbb');

person2.on('call2', function () {
    console.log('person2');
});

console.log(person1);
console.log(person2);
console.log('ccccc');




person1.emit('call1'); // 输出 'person1'
person1.emit('call2'); // 没有输出
person2.emit('call1'); // 没有输出
person2.emit('call2'); // 输出 'person2'

console.log(person2.handles ===person1.handles);

观察者的使用场合就是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式。

总的来说,观察者模式所做的工作就是在解耦,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响到另一边的变化。

  • 优点
    时间上解耦对象间解耦
  • 缺点
    创建这个函数同样需要内存,过度使用会导致难以跟踪维护
    原文作者:设计模式
    原文地址: https://segmentfault.com/a/1190000013398875
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞