javascript設(shè)計(jì)模式之中介者模式Mediator
一,總體概要
1,筆者淺談
我們從日常的生活中打個(gè)簡單的比方,我們?nèi)シ课葜薪樽夥?,房屋中介人在租房者和房東出租者之間形成一條中介。租房者并不關(guān)心他租誰的房。房東出租者也不關(guān)心他租給誰。因?yàn)橛兄薪榈拇嬖?,這場交易才變得如此方便。
在軟件的開發(fā)過程中,勢必會(huì)碰到這樣一種情況,多個(gè)類或多個(gè)子系統(tǒng)相互交互,而且交互很繁瑣,導(dǎo)致每個(gè)類都必須知道他需要交互的類,這樣它們的耦合會(huì)顯得異常厲害。牽一發(fā)而動(dòng)全身,后果很嚴(yán)重,大熊很生氣!~~~~(>_<)~~~~
好了,既然問題提出來了,那有請(qǐng)我們這期的主角------中介者模式出場吧

中介者的功能就是封裝對(duì)象之間的交互。如果一個(gè)對(duì)象的操作會(huì)引起其他相關(guān)對(duì)象的變化,而這個(gè)對(duì)象又不希望自己來處理這些關(guān)系,那么就可以去找中介者,讓它來處理這些麻煩的關(guān)系??聪旅娴男±樱?/p>
var Participant = function(name) {
this.name = name;
this.chatroom = null;
};
Participant.prototype = {
send: function(message, to) {
this.chatroom.send(message, this, to);
},
receive: function(message, from) {
log.add(from.name + " to " + this.name + ": " + message);
}
};
var Chatroom = function() {
var participants = {};
return {
register: function(participant) {
participants[participant.name] = participant;
participant.chatroom = this;
},
send: function(message, from, to) {
if (to) {
to.receive(message, from);
} else {
for (key in participants) {
if (participants[key] !== from) {
participants[key].receive(message, from);
}
}
}
}
};
};
var log = (function() {
var log = "";
return {
add: function(msg) { log += msg + "\n"; },
show: function() { alert(log); log = ""; }
}
})();
function run() {
var yoko = new Participant("Yoko");
var john = new Participant("John");
var paul = new Participant("Paul");
var ringo = new Participant("Ringo");
var chatroom = new Chatroom();
chatroom.register(yoko);
chatroom.register(john);
chatroom.register(paul);
chatroom.register(ringo);
yoko.send("All you need is love.");
yoko.send("I love you John.");
john.send("Hey, no need to broadcast", yoko);
paul.send("Ha, I heard that!");
ringo.send("Paul, what do you think?", paul);
log.show();
}
在示例代碼中我們有四個(gè)參與者,加入聊天會(huì)話通過注冊一個(gè)聊天室(中介)。每個(gè)參與者的參與對(duì)象的代表。參與者相互發(fā)送消息和聊天室的處理路由。
這里的聊天室對(duì)象就起到了中介的作用,協(xié)調(diào)其他的對(duì)象,進(jìn)行合理的組織,降低耦合。
二,源碼案例參考
我們應(yīng)該很熟悉MVC三層模型實(shí)體模型(Model)、視圖表現(xiàn)層(View)還有控制層(Control/Mediator)。
控制層便是位于表現(xiàn)層與模型層之間的中介者。籠統(tǒng)地說MVC也算是中介者模式在框架設(shè)計(jì)中的一個(gè)應(yīng)用。

三,案例引入
function Player(name) {
this.points = 0;
this.name = name;
}
Player.prototype.play = function () {
this.points += 1;
mediator.played();
};
var scoreboard = {
element:document.getElementById('results'),
update:function (score) {
var i, msg = '';
for (i in score) {
if (score.hasOwnProperty(i)) {
msg += '<p><strong>' + i + '<\/strong>: ';
msg += score[i];
msg += '<\/p>';
}
}
this.element.innerHTML = msg;
}
};
var mediator = {
players:{},
setup:function () {
var players = this.players;
players.home = new Player('Home');
players.guest = new Player('Guest');
},
played:function () {
var players = this.players,
score = {
Home:players.home.points,
Guest:players.guest.points
};
scoreboard.update(score);
},
keypress:function (e) {
e = e || window.event;
if (e.which === 49) {
mediator.players.home.play();
return;
}
if (e.which === 48) {
mediator.players.guest.play();
return;
}
}
};
mediator.setup();
window.onkeypress = mediator.keypress;
setTimeout(function () {
window.onkeypress = null;
console.log('Game over!');
}, 30000);
四,總結(jié)一下
Why Mediator ?
各個(gè)對(duì)象之間的交互操作非常多,每個(gè)對(duì)象的行為操作都依賴彼此對(duì)方,修改一個(gè)對(duì)象的行為,同時(shí)會(huì)涉及到修改很多其他對(duì)象的行為,
如果使用Mediator模式,可以使各個(gè)對(duì)象間的耦合松散,只需關(guān)心和 Mediator的關(guān)系,使多對(duì)多的關(guān)系變成了一對(duì)多的關(guān)系,
可以降低系統(tǒng)的復(fù)雜性,提高可修改擴(kuò)展性。
使用中介者模式的場合
1.一組定義良好的對(duì)象,現(xiàn)在要進(jìn)行復(fù)雜的通信。
2.定制一個(gè)分布在多個(gè)類中的行為,而又不想生成太多的子類。
可以看出,中介對(duì)象主要是用來封裝行為的,行為的參與者就是那些對(duì)象,但是通過中介者,這些對(duì)象不用相互知道。(迪米特法則的具體實(shí)現(xiàn))
使用中介者模式的優(yōu)點(diǎn):
1.降低了系統(tǒng)對(duì)象之間的耦合性,使得對(duì)象易于獨(dú)立的被復(fù)用。
2.提高系統(tǒng)的靈活性,使得系統(tǒng)易于擴(kuò)展和維護(hù)。
使用中介者模式的缺點(diǎn):
中介者模式的缺點(diǎn)是顯而易見的,因?yàn)檫@個(gè)“中介“承擔(dān)了較多的責(zé)任,所以一旦這個(gè)中介對(duì)象出現(xiàn)了問題,那么整個(gè)系統(tǒng)就會(huì)受到重大的影響。
相關(guān)文章
document.onreadystatechange事件的用法分析
這里主要介紹document.onreadystatechange事件的使用方法, 一般多用于實(shí)時(shí)監(jiān)控用戶的輸入2009-10-10
基于BootStrap Metronic開發(fā)框架經(jīng)驗(yàn)小結(jié)【四】Bootstrap圖標(biāo)的提取和利用
通過本文主要介紹如何提取Bootstrap的圖標(biāo)信息,存儲(chǔ)到數(shù)據(jù)庫里面為我所用,非常具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-05-05
firefox下javascript實(shí)現(xiàn)高亮關(guān)鍵詞的方法
“點(diǎn)睛”的廣告代碼,很牛B,本想從中找出在FireFox下如何實(shí)現(xiàn)findText及pasteHTML類似效果的,我看了大半天,楞是沒有看出個(gè)所以然來!還是自己慢慢研究吧。2007-07-07
JavaScript返回0-1之間隨機(jī)數(shù)的方法
這篇文章主要介紹了JavaScript返回0-1之間隨機(jī)數(shù)的方法,涉及javascript中Math對(duì)象random方法的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
JavaScript實(shí)現(xiàn)抽獎(jiǎng)器效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)抽獎(jiǎng)器效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
JS 實(shí)現(xiàn)banner圖片輪播效果(鼠標(biāo)事件)
js實(shí)現(xiàn)banner圖片輪播效果,通過鼠標(biāo)點(diǎn)擊左右可切換圖片,具體實(shí)現(xiàn)代碼大家參考下本文2017-08-08
js將圖片轉(zhuǎn)base64的兩種實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于js將圖片轉(zhuǎn)base64的兩種實(shí)現(xiàn)方法,Base64是網(wǎng)絡(luò)上最常見的用于傳輸8Bit字節(jié)碼的編碼方式之一,Base64就是一種基于64個(gè)可打印字符來表示二進(jìn)制數(shù)據(jù)的方法,需要的朋友可以參考下2023-07-07
JS+WCF實(shí)現(xiàn)進(jìn)度條實(shí)時(shí)監(jiān)測數(shù)據(jù)加載量的方法詳解
這篇文章主要介紹了JS+WCF實(shí)現(xiàn)進(jìn)度條實(shí)時(shí)監(jiān)測數(shù)據(jù)加載量的方法,結(jié)合實(shí)例形式分析了大量數(shù)據(jù)導(dǎo)入過程中前臺(tái)js與后臺(tái)WCF交互實(shí)現(xiàn)實(shí)時(shí)顯示加載進(jìn)度的相關(guān)操作技巧,需要的朋友可以參考下2017-12-12

