观察者模式

啥叫观察者模式,我的理解就是,在战场上我看见敌军发射一枚炮弹,我告诉我的士兵卧倒,我就是一个观察者。又好比现在的狙击手,身边都有一个观察者,具体叫啥不知道,反正人家发现敌人了,就和狙击手说默默方向有人,打,完咯狙击手就往那个方向打,指哪打哪,这也是观察者的一种运用吧。

// 定义事件
function incident(){
    // 想想存放啥事件
   this.fight = {};
}
incident.prototype={
    // 先把打仗的事件放入(订阅模式)
    on: function (type, handle) {
        if(!this.fight[type]){
            this.fight[type] = [];
        }
        this.fight[type].push(handle);
    },
    // 开始干仗了
    emit: function () {
        // 来获取观察者看到的事件
       let type = Array.prototype.shift.call(arguments);
        //    console.log(type,'我看到炮弹了!!')
       // 判断不是个方法直接干掉(发布假情报的干掉)
        if(!this.fight[type]){
            return false;
        }
        // 看到有几个方法,执行几个
        for (let i = 0; i < this.fight[type].length; i++) {
            let handle = this.fight[type][i];
            //执行事件
           handle.apply(this, arguments);
        }
    },
    //需要说明的是Array.prototype.shift.call(arguments)这句代码,arguments对象是function的内置对象,可以获取到调用该方法时传入的实参数组。
    // shift方法取出数组中的第一个参数,就是type类型。
    // 打完仗后
    off: function (type, handle) {
        // 取消掉哪一个观察者
        fight = this.fight[type];
        // 判断有观察者
        if(fight){
            // 没方法直接置空数组
            if(!handle){
                fight.length = 0;//清空数组
           }else{
            console.log(fight.length)
            // 把多个方法删除掉其中一个
            for (let i = 0; i < fight.length; i++) {
                    let _handle = fight[i];
                    if(_handle === handle){
                        fight.splice(i,1);
                    }
                }
            }
        }
    }
}
let p1 = new incident();
 p1.on('打仗了', function (name) {
     console.log('打仗了: '+ name);
 });
 p1.emit('打仗了','我知道了');
// console.log('===============');
 let p2 = new incident();
 let fn = function (name) {
     console.log('炮弹来了: '+ name);
 };
 let fn2 = function (name) {
    console.log('前方有敌人: '+ name);
};
 p2.on('炮弹来了', fn);
 p2.on('前方有敌人', fn2);
 p2.emit('炮弹来了','卧槽,卧倒');
 p2.emit('前方有敌人','在哪,我没看到啊!');
// console.log('===============');
p2.off('炮弹来了', fn);
p2.emit('炮弹来了','我不干了');

  

总结(1):

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

使用观察者模式的好处:

  1. 支持简单的广播通信,自动通知所有已经订阅过的对象。
  2. 页面载入后目标对象很容易与观察者存在一种动态关联,增加了灵活性。
  3. 目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。

总结(自结):

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

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

原文地址:https://www.cnblogs.com/yishifuping/p/10994440.html