观察者模式
观察者模式
/* 经典观察者模式 * 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(); //按钮通知
......//相关的逻辑和扩展方法,这样就解耦了,不会强耦合。