引见
这个形式用来作为中间人,一个把宣布者和定阅者架接在一起的代办。宣布者是当完成某些历程的时刻触发事宜的对象,定阅者是愿望当宣布者宣布的时刻愿望被关照的对象。
生涯中有一个很好地例子,广播电台,人们会把频道调到他们最喜欢的节目。广播站不晓得观众听得是什么或许他们正在听什么。他只须要宣布他们的节目就可以啦。观众也不晓得广播站制造节目的历程。他们只需在他们最喜欢的节目运转的时刻把台调到对应的频道或许示知朋侪就行。
宣布/定阅者形式完成了松耦合:你可以让宣布者宣布音讯,定阅者接收音讯而不是寻觅一种体式格局把两个星散的体系衔接在一起。
上风
松耦合
宣布者不须要晓得定阅者的数目,定阅者听得话题或许定阅者是经由过程什么体式格局运转的。他们可以互相独登时运转,如许就可以让你离开开辟这两部分而不须要忧郁对状况或完成的任何纤细的影响。
可扩大性
宣布/定阅形式可以让体系在不管什么时刻没法负载的时刻扩大
更清洁地设想
充足地利用好宣布/定阅形式,你不能不深切地思索差别的组件是怎样交互的。这通常会让我们有更清洁地设想由于我们对解耦和松耦合的强调。
灵活性
你不须要忧郁差别的组件是怎样组合在一起的。只需他们配合恪守一份协定
轻易测试
你可以很好地找出宣布者或定阅者是不是会取得毛病的信息
瑕玷
宣布/定阅形式最大的有点是解耦,但同时也是最大的瑕玷:
中间人或许不会关照体系音讯传送的状况。所以我们没法晓得音讯传送是胜利的照样失利的。紧耦合是须要保证这一点的。
宣布者不晓得定阅者的状况,反之亦然,如许的话,你基础不晓得在另一端是不是会没有题目?
跟着定阅者和宣布者数目的增添,不停增添的音讯传送回致使架构的不稳定,轻易在负载大的时刻出题目
攻击者(歹意的宣布者)可以入侵体系而且扯开它。这会致使歹意的音讯被宣布,定阅者可以取得他们之前并不能取得的音讯。
更新宣布者和定阅者的关联会是一个很难的题目,由于毕竟他们基础不认识对方。
须要中间人/代办商,音讯范例和相干的划定规矩会给体系增添一些复杂度
结论
实际没有银弹,然则这个形式是设想松耦合体系的很好地体式格局。这和RSS,Atom和PubSubHubbub的头脑一样。
宣布/定阅形式例子(Javascript)
var makePubSub=function(){
var callbacks={},
publish=function(){
//Turn arguments object into real array
var args=Array.prototype.slice.call(arguments,0);
//Extract the event name which is the first entry
var ev=args.shift();
//Return if callbacks object doesn't contain
//any entry for event
var list,i,l;
if(!callbacks[ev]){
return this;
}
list=callbacks[ev];
//Invoke the callbacks,passing in the rest of parameters
for(i=0,l=list.length;i<l;i++){
list[i].apply(this,args);
}
return this;
},
subscribe=function(ev,callback){
//Check if ev is already registered
//If it isn't create an array entry for it
if(!callbacks[ev]){
callbacks[ev]=[];
}
callbacks[ev].push(callback);
return this;
};
return {pub:publish,sub:subscribe};
}
test=makePubSub();
test.sub("alert",function(){alert("hell0");})
test.pub("alert");