《js设计模式》中对Observer的定义:
一个对象(称为subject)维持一系列依赖于它(观察者)的对象,将有关状态的任何变动自动通知给它们。jquery
《设计模式:可服用面向对象软件的基础》中对Observer的定义:
一个或多个观察者对目标的状态感兴趣,它们经过将本身依附在目标对象上以便注册所感兴趣的内容。目标状态发生改变而且观察者可能对这些改变感兴趣,就会发送一个通知消息,调用每一个观察者的更新方法。当观察者再也不对目标感兴趣时,他们能够简单地将本身从中分离。segmentfault
下面看一个观察者模式的例子:设计模式
//观察者列表 function ObserverList() { this.observerList = []; } ObserverList.prototype.add = function(obj) { return this.observerList.push(obj); }; ObserverList.prototype.count = function() { return this.observerList.length; }; ObserverList.prototype.get = function(index) { if(index > -1 && index < this.observerList.length) { return this.observerList[index ]; } }; ObserverList.prototype.indexOf = function(obj, startIndex) { var i = startIndex; while(i < this.observerList.length) { if(this.observerList[i] === obj) { return i; } i++; } return -1; }; ObserverList.prototype.removeAt = function(index) { this.observerList.splice(index, 1); }; //目标 function Subject() { this.observers = new ObserverList(); } Subject.prototype.addObserver = function(observer) { this.observers.add(observer); }; Subject.prototype.removeObserver = function(observer) { this.observers.removeAt(this.observers.indexOf(observer, 0)); }; Subject.prototype.notify = function(context){ var observerCount = this.observers.count(); for(var i=0; i < observerCount; i++){ this.observers.get(i).update(context); } }; //观察者 function Observer(name, subject) { this.name = name; this.subject = subject; this.subscribe(this.subject); } Observer.prototype.update = function(context) { console.log('observer:' + this.name + ' content:' + context); } Observer.prototype.subscribe = function(subject) { this.subject.addObserver(this); } var subject1 = new Subject(); var subject2 = new Subject(); var observer1 = new Observer('observer1', subject1); var observer2 = new Observer('observer2', subject1); var observer3 = new Observer('observer3', subject2); subject1.notify('999感冒灵'); subject2.notify('999胃泰'); //observer:observer1 content:999感冒灵 //observer:observer2 content:999感冒灵 //observer:observer3 content:999胃泰
经常使用的场景promise
下面咱们来看一个发布订阅的具体实现;微信
var pubsub={}; (function(q){ var topics={}, subUid=-1, subscribers, len; //发布广播事件,包含特定的topic名称和参数 q.publish=function(topic, args){ if(!topics[topic]){ return false; } subscribers=topics[topic]; len=subscribers ? subscribers.length : 0; while(len--){ subscribers[len].func(topic, args); } return this; }; q.subscribe=function(topic, func){ if(!topics[topic]){ topics[topic]=[]; } var token=(++subUid).toString(); topics[topic].push({ token:token, func:func }); return token; }; q.unsubscribe=function(token){ for(var m in topics){ if(topics[m]){ for(var i = 0, j=topics[m].length; i < j; i++){ if(topics[m][i].token === token){ topics[m].splice(i, 1); return token; } } } } return this; }; })(pubsub); function log1(topic ,data){ console.log(topic , data); } function log2(topic ,data){ console.log("Topic is "+topic+" Data is "+data); } pubsub.subscribe("sss",log2); pubsub.subscribe("sss",log1); pubsub.subscribe("cccc",log2); pubsub.subscribe('aaa', log1); pubsub.publish("sss","aaaaa1"); pubsub.publish("cccc","ssssss"); pubsub.publish('aaa', 'hahahahah'); //sss aaaaa1 //Topic is sss Data is aaaaa1 //Topic is cccc Data is ssssss //aaa hahahahah
Observer模式要求但愿接收到主题通知的观察者或对象必须订阅内容改变的事件。如图:
Publish/Subscribe模式比较观察者模式则多了一个相似于话题调度中心的流程,发布者和订阅者解耦。this
观察者模式更像是去咖啡店点咖啡,向店家点一杯咖啡,而后作好后店家会送过来,我和店家是直接有交互的。spa
发布订阅模式就像是咱们微信里面订阅公众号,发布者把文章发布到这个公众号,咱们订阅公众号后就会收到发布者发布的文章,咱们能够关注和取消关注这个公众号。prototype
感兴趣的小伙伴能够移步本身动手实现一个Promise设计
JS设计模式之Obeserver(观察者)模式、Publish/Subscribe(发布/订阅)模式
JS设计模式之Factory(工厂)模式
JS设计模式之Singleton(单例)模式
JS设计模式之Facade(外观)模式
JS设计模式之Module(模块)模式、Revealing Module(揭示模块)模式
JS设计模式之Mixin(混入)模式code