中介者模式的作用就是解除對象與對象之間的緊耦合關係,它也稱'調停者'。所有的對像都通過中介者對象來通信,而不是相互引用,所以當一個對象發生改變時,只需要通知中介者即可。
如:機場的指揮塔,每架飛機都只需要和指揮塔通信即可,指揮塔知道每架飛機的飛行狀況,可以安排所有起降時間,調整航線等
中介者模式符合迪米特法則,即最少知識原則,指一個對象應該盡可能少地了解另外的對象。如果對象之間的耦合性太高,則改變一個對象,會牽動很多對象,難於維護。當對象耦合很緊時,要修改一個對象而不影響其它的對像是很困難的。
如果對象之間的複雜耦合確實導致調用和維護出現了困難,而且這些耦合度隨項目的變化呈指數增長,那我們就可以考慮用中介者模式來重構代碼!中介者通過解耦來提升代碼的可維護性。
例子1:遊戲
玩家對像是通過Player()構造函數來創建的,有自己的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()方法中創建遊戲者,然後放後players屬性以便後續使用。 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 secondssetTimeout(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設計模式與開發實踐》
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。