观察者模式

观察者模式

/* 经典观察者模式
 * Observer、Subject
 * 也可以增加1级抽象,不过JS继承太麻烦,此处从简
 * 手动维护List
 */

// Subject
function Subject(name) {
    this.name = name;
    this.list = [];
}
// 关注
Subject.prototype.regist = function(obj) {
    this.list.push(obj);
};
// 取消关注
Subject.prototype.unregist = function(obj) {
    var list = this.list;

    for(var i = 0, len = list.length; i < len; i++) {
        if (list[i] === obj) {
            list.splice(i, 1);
        }
    }
};
// 通知所有粉丝
Subject.prototype.notify = function() {
    var list = this.list;

    for(var i = 0, len = list.length; i < len; i++) {
        list[i].update({data: this.name});
    }
};

// Observer
function Observer(id) {
    this.id = id;
    // 供Subject调用的更新方法
    this.update = function(dataObj) {
        // ...
        console.log(this.id + ' received ' + dataObj.data + '\'s update');
    };
}

// test
var subject = new Subject('My Topic');
var observer1 =  new Observer(1);
var observer2 =  new Observer(2);
var observer3 =  new Observer(3);

subject.regist(observer1);
subject.regist(observer2);
subject.notify();   // 主题更新,通知所有观察者

subject.regist(observer3);  // 新加入observer3
subject.notify();

// observer1不玩了
subject.unregist(observer1);
subject.notify();

观察者模式经典写法

观察者模式,就是让观察者们注册到被观察者身上。一个被观察者,影响很多观察者的行为。

举个例子:

比如提交验证的时候,当一个按钮被点击的时候,很多input都会根据验证的情况去更新自己的颜色和提示信息。

一般的强耦合写法是:

button.on('click', function(){

  $('input') 循环判断值,

      if(值 不存在) {

    $('input').css('background','red'); //设置提示消息

      }

});

或者

function ButtonControl(dom){

              this.dom = dom;

    this.init();

}

 

ButtonControl.prototype.init = function(){

  dom.on('click', function(){

    //对input的显示逻辑处理

  }):

}

这样,button自己的方法和input的判断就耦合在一起了。如果想单独维护input修改的颜色方法,得去button的点击方法里面写

如果想对input自己拥有的逻辑维护,就很难,其他的input的逻辑,得歇到别的地方,比如点击弹框等方法。

 

所以松耦合的写法,就是观察者模式

//按钮的方法

function ButtonControl(dom){

  this.dom = dom;

  this.inputs = [];

  this.init();

}

 

ButtonControl.prototype.init = function(){

       const self = this;

  this.dom.on('click', function(){

    self.notify();

              //然后根据input的值来判断请求ajax

    //其他的行为

  });

}

ButtonControl.prototype.notify = function( ){

       this.inputs.forEach((dom) => {

    dom.update();

  });  

}

ButtonControl.prototype.bindInputs = function(doms){

  this.inputs  = doms;

}  

//Input的方法

function InputControl = function(dom){

  this.dom = dom;

}

InputControl.prototype.update = function(){

//对input的修改就单独在Input里面维护

  this.dom.css('color', 'red');

}

var buttom = new ButtonControl(dom);

var input1 = new InputControl(input1);

var input2 = new InputControl(input2);

buttom .bindInputs([input1, input2]);

buttom.notify(); //按钮通知

......//相关的逻辑和扩展方法,这样就解耦了,不会强耦合。

 

posted on 2021-01-05 17:29  chenyi4  阅读(98)  评论(0编辑  收藏  举报

导航