輕松掌握JavaScript中介者模式
中介者模式的作用就是解除對象與對象之間的緊耦合關系,它也稱‘調停者'。所有的對象都通過中介者對象來通信,而不是相互引用,所以當一個對象發(fā)生改變時,只需要通知中介者即可。
如:機場的指揮塔,每架飛機都只需要和指揮塔通信即可,指揮塔知道每架飛機的飛行狀況,可以安排所有起降時間,調整航線等
中介者模式符合迪米特法則,即最少知識原則,指一個對象應該盡可能少地了解另外的對象。如果對象之間的耦合性太高,則改變一個對象,會牽動很多對象,難于維護。當對象耦合很緊時,要修改一個對象而不影響其它的對象是很困難的。
如果對象之間的復雜耦合確實導致調用和維護出現了困難,而且這些耦合度隨項目的變化呈指數增長,那我們就可以考慮用中介者模式來重構代碼!中介者通過解耦來提升代碼的可維護性。
例子1:游戲
玩家對象是通過Player()構造函數來創(chuàng)建的,有自己的points和name屬性。原型上的play()方法負責給自己加一分然后通知中介者:
function Player(name) {
this.points = 0;
this.name = name;
}
Player.prototype.play = function () {
this.points += 1;
mediator.played();
};
scoreboard對象(計分板)有一個update()方法,它會在每次玩家玩完后被中介者調用。計分析根本不知道玩家的任何信息,也不保存分數,它只負責顯示中介者給過來的分數:
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;
}
};
現在我們來看一下mediator對象(中介者)。在游戲初始化的時候,在setup()方法中創(chuàng)建游戲者,然后放后players屬性以便后續(xù)使用。played()方法會被游戲者在每輪玩完后調用,它更新score哈希然表然后將它傳給scoreboard用于顯示。最后一個方法是keypress(),負責處理鍵盤事件,決定是哪位玩家玩的,并且通知它:
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; // IE
if (e.which === 49) { // key "1"
mediator.players.home.play();
return;
}
if (e.which === 48) { // key "0"
mediator.players.guest.play();
return;
}
}
};
最后一件事是初始化和結束游戲:
// go!
mediator.setup();
window.onkeypress = mediator.keypress;
// game over in 30 seconds
setTimeout(function () {
window.onkeypress = null;
alert('Game over!');
}, 30000);
例子2:賣手機
var goods = { //庫存
'red|32G':3,
'red|16G':5,
'blue|32G':3,
'blue|16G':6
}
//中介者
var mediator = (function(){
function id(id){
return document.getElementById(id);
}
var colorSelect = id('colorSelect'),
memorySelect = id('memorySelect'),
numberInput = id('numberInput'),
colorInfo = id('colorInfo'),
memoryInfo = id('memoryInfo'),
numberInfo = id('numberInfo'),
nextBtn = id('nextBtn');
return{
changed:function(obj){
var color = colorSelect.value,
memory = memorySelect.value,
number = numberInput.value,
stock = goods[color+'|'+memory];
if(obj === colorSelect){
colorInfo.innerHTML = color;
}else if(obj === memorySelect){
memoryInfo.innerHTML = memory;
}else if(obj === numberInput){
numberInfo.innerHTML = number;
}
if(!color){
nextBtn.disabled = true;
nextBtn.innerHTML = '請選擇手機顏色';
return;
}
if(!memory){
nextBtn.disabled = true;
nextBtn.innerHTML = '請選擇內存大小';
return;
}
if(Number.isInteger(number-0) && number > 0){
nextBtn.disabled = true;
nextBtn.innerHTML = '請輸入正確的購買數量';
return;
}
nextBtn.disabled = false;
nextBtn.innerHTML = '放入購物車';
}
}
})();
//添加事件
colorSelect.onchange = function(){
mediator.changed(this);
}
memorySelect.onchange = function(){
mediator.changed(this);
}
numberInput.onchange = function(){
mediator.changed(this);
}
參考文獻: 《JavaScript模式》 《JavaScript設計模式與開發(fā)實踐》
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
window.addeventjs事件驅動函數集合addEvent等
addEvent()、removeEvent()、handleEvent()、fixEvent()[2008-02-02
JavaScript中split與join函數的進階使用技巧
這篇文章主要介紹了JavaScript中split與join函數的進階使用技巧,split和join通常被用來操作數組和字符串之間的轉換,需要的朋友可以參考下2016-05-05

