发布-订阅模式本身不属于设计模式,是由观察者模式衍生出来的一种模式。所以在了解发发布订阅模式前要了解观察者模式。
什么是观察者模式?
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。(官方定义)
观察者模式例子:
以购物者和超市的商品为例,超市的商品依赖于购物者去购买,但是购物者也依赖于超市的商品,所以二者的耦合性太高。
发布订阅模式的背景:
由于观察者模式的耦合度太高,也就是Subject和Observer的依赖关系太大,所以就衍生出了发布订阅模式。
那什么是发布订阅模式?
订阅者把自己想订阅的事件注册到调度中心,当发布者发布该事件到调度中心,也就是该事件触发时,由调度中心统一调度订阅者注册到调度中心的处理代码。调度中心起到了降低耦合度,让订阅者和发布者的依赖关系没有那么强,需要通过调度中心这个三方进行处理订阅者和发布者的消息。
发布订阅模式例子:
淘宝的发布者、订阅者、店铺。如果你喜欢一个店铺的商品,但是最近没有,那么你可以进行关住店铺,当有货时发布者就会进行发布,发布到店铺后,因为你关注了店铺,所以订阅者(也就是你)就会收到货品到货的通知。
发布订阅模式的代码:
var Event = (function(){
var list = {},
listen,
trigger,
// 发布者listen
listen = function(key,fn){
if(!list[key]) { // 关键的一步
list[key] = []; // 在这里需要进行注册,验证是否有该key
}
list[key].push(fn);
};
// 订阅者trigger
trigger = function(){
var key = Array.prototype.shift.call(arguments),
fns = list[key];
if(!fns || fns.length === 0) {
return false;
}
for(var i = 0, fn; fn = fns[i++];) {
fn.apply(this,arguments);
}
};
return {
listen: listen,
trigger: trigger
}
})();
// 测试代码如下:
Event.listen("color",function(size) {
console.log("尺码为:"+size); // 打印出尺码为42
});
Event.trigger("color",42);
总结:发布订阅模式的话就是为了解决各模块代码逻辑的耦合性,耦合性太高的话就会造成模块的可复用性降低,严重也可能造成涟漪效应;但是在开发当中我们建议的是提高模块的复用性,这样可大大提高程序的效率。发布订阅模式通俗的将就是在发布者和订阅者之间增加一个第三方,来降低耦合。vue的双向绑定就是利用了这个模式,通过数据劫持和发布订阅模式实现。(下周会总结数据劫持和发布订阅模式)