一。中介者模式
中介,也就是第三方,本來是雙方直接交互,引入中介之後,所有交互都必須通過第三方來完成
比如本來是對講機直接通信,現在改用郵件了,由郵件服務器負責轉發。對應到模塊交互上就是本來的網狀結構現在變成星狀結構了,各個模塊之間的依賴被降低了,統一依賴中心點(中介者),同時中心點也因此獲得了更多的控制權限,比如可以群發、可以冒泡通知等等
所有模塊之間的交互必須通過中介者進行,模塊彼此並不熟悉,只要把消息發布給中介者,中介自然就會通知需要知情(訂閱了相應主題)的人。系統以這樣的機制運行,中介者是控制核心
二。中介者模式的具體實現
1. 最簡單的中介者模式
var mediator = (function() {
var topics = {},
subUid = -1;
var publish = function(topic, args) {
if (!topics[topic]) {
return false;
}
var subscribers = topics[topic],
len = subscribers ? subscribers.length : 0;
while (len--) {
subscribers[len].func(topic, args);
}
return true;
};
var subscribe = function(topic, func) {
if (!topics[topic]) {
topics[topic] = [];
}
var token = (++subUid).toString();
topics[topic].push({
token: token,
func: func
});
return token;
};
return {
publish: publish,
subscribe: subscribe,
// 好像確實沒有比 installTo 更合適的名字
installTo: function(obj) {
obj.publish = publish;
obj.subscribe = subscribe;
}
}
}());
// 具體應用
var mod1 = {
run: function(arg) {
console.log('mod1 received ' + arg);
}
};
var mod2 = {};
var topic = 'myTopic';
mediator.installTo(mod1);
mediator.installTo(mod2);
// mod1 訂閱消息
mod1.subscribe(topic, function(t, arg) {
mod1.run(arg);
});
// mod2 發布消息
mod2.publish(topic, 'data');
乍看和前面介紹的 [發布/訂閱模式] 沒什麼區別,例子中體現的一個區別是任何模塊都可以發布消息,而發布/訂閱模式中觀察者只能被動接收消息,具體差異下面展開詳細介紹
2. 功能強大的中介者模式
http://thejacklawson.com/Mediator.js/index.html 提供了一個功能強大的實現,支持 topic 命名空間、消息冒泡、優先級等等
源碼(帶注釋)見http://thejacklawson.com/Mediator.js/mediator.html,或者 github
三。中介��模式與發布/訂閱模式
(當然,發布/訂閱模式源自觀察者模式,中介者模式算是孫子輩的。)
從實現上來看,中介者模式和發布/訂閱模式非常相似,甚至不仔細看就發現不了差異。主要區別如下:
- 通信方式
中介者模式中每個模塊都可以發布消息(中介者本身也可以發布消息),而發布/訂閱模式中觀察者只能被動的等待消息
- 模塊依賴結構
中介者模式是星狀結構,中介者是一個*「控制點」,而發布/訂閱模式中,發布訂閱機制本身是一個「控制層」*,意味著高層可以通過控制層操作下層模塊(雖然高層也可以通過中介者控制下層模塊,但這不是星狀結構的本意)
- 信息發布方式
由多對多變成了多對一,所有模塊都只能和中介者直接對話
缺點:
- 單一故障點
這是中介者模式最大的缺點,發布/訂閱模式也存在這個缺點,但中介者模式表現得更加銳利(結合「控制點」和「控制層」理解)
- 性能下降
模塊間必須通過第三方才能交互,相比直接交互肯定存在性能下降,是設計模式共有的副作用
- 邏輯實現難度增加
鬆散耦合導致系統難以控制,很難通過僅僅關註廣播來確定一個系統如何做出反應,必須把完整邏輯拆分到各個 Topic 下,增加了實現上的複雜度
參考資料
- 《JavaScript 設計模式》
暫無評論,快來發表你的看法吧