學(xué)習(xí)JavaScript設(shè)計(jì)模式之中介者模式
一、定義
面向?qū)ο笤O(shè)計(jì)鼓勵(lì)將行為分布到各個(gè)對(duì)象中,把對(duì)象劃分成更小的粒度,有助于增強(qiáng)對(duì)象的可復(fù)用性。但由于這些細(xì)粒度對(duì)象之間的聯(lián)系激增,又可能反過來降低它們的可復(fù)用性。
中介者模式的作用就是解除對(duì)象與對(duì)象之間的緊耦合關(guān)系。
二、示例:購買商品
- 假設(shè)我們正在開發(fā)一個(gè)購買手機(jī)的頁面,購買流程中,可以選擇手機(jī)顏色以及輸入購買數(shù)量,同時(shí)頁面中可以對(duì)應(yīng)展示輸入內(nèi)容。還有一個(gè)按鈕動(dòng)態(tài)顯示下一步操作(該顏色庫存量充足,顯示下一步;否則顯示庫存不足)。
<div>
<span>請選擇顏色</span>
<select id="selColor">
<option value="roseGold">玫瑰金</option>
<option value="luxuryGold">土豪金</option>
</select>
</div>
<div>
<span>請輸入購買數(shù)量:</span>
<input type="text" id="selNum" />
</div>
<div>
<span>您選擇的顏色為:</span><strong id="conColor"></strong>
<span>您選擇的數(shù)量為:</span><strong id="conNum"></strong>
</div>
<button id="nextBtn">加入購物車</button>
// 庫存量
var goods = {
roseGold: 10,
luxuryGold: 10
};
var colorSelect = document.getElementById("selColor"),
numberInput = document.getElementById("selNum"),
colorInfo = document.getElementById("conColor"),
numberInfo = document.getElementById("conNum"),
nextBtn = document.getElementById("nextBtn");
colorSelect.onchange = function() {
var color = colorSelect.value, // 顏色
number = +numberInput.value, // 數(shù)量
stock = goods[color]; // 對(duì)應(yīng)顏色的庫存量
colorInfo.innerHTML = color;
if(!color) {
nextBtn.disabled = true;
nextBtn.innerHTML = "請選擇手機(jī)顏色";
return;
}
if(!number || (((number - 0) | 0) !== (number - 0))) {
nextBtn.disabled = true;
nextBtn.innerHTML = "請選擇手機(jī)數(shù)量";
return;
}
if( number > stock) {
nextBtn.disabled = true;
nextBtn.innerHTML = "庫存不足";
return;
}
nextBtn.disabled = false;
nextBtn.innerHTML = "加入購物車";
};
/* 購買數(shù)量做同樣處理 */
當(dāng)頁面中新增加另外一個(gè)下拉列表框,代表手機(jī)內(nèi)存,上述代碼改動(dòng)面很大。
三、引入中介模式
所有的節(jié)點(diǎn)對(duì)象只跟中介者通信。
當(dāng)下拉選擇框selColor、selMemory亦或文本框selNum發(fā)生了事件行為時(shí),僅通知中介者它們被改變了,同時(shí)把自己當(dāng)做參數(shù)傳入中介者,以便中介者辨別是誰發(fā)生了改變,剩下的事情交給中介者對(duì)象來完成。
<div>
<span>請選擇顏色:</span>
<select id="selColor">
<option value="roseGold">玫瑰金</option>
<option value="luxuryGold">土豪金</option>
</select>
</div>
<div>
<span>請選擇內(nèi)存:</span>
<select id="selMemory">
<option value="16G">16G</option>
<option value="64G">64G</option>
</select>
</div>
<div>
<span>請輸入購買數(shù)量:</span>
<input type="text" id="selNum" />
</div>
<div>
<span>您選擇的顏色為:</span><strong id="conColor"></strong>
<span>您選擇的內(nèi)存為:</span><strong id="conMemory"></strong>
<span>您選擇的數(shù)量為:</span><strong id="conNum"></strong>
</div>
<button id="nextBtn">加入購物車</button>
// 庫存量
var goods = {
"roseGold|16G": 10,
"roseGold|32G": 10,
"luxuryGold|16G": 10,
"luxuryGold|32G": 10
};
var colorSelect = document.getElementById("selColor"),
memorySelect = document.getElementById("selMemory"),
numberInput = document.getElementById("selNum"),
colorInfo = document.getElementById("conColor"),
memeryInfo = document.getElementById("conMemory"),
numberInfo = document.getElementById("conNum"),
nextBtn = document.getElementById("nextBtn");
var mediator = (function() {
return {
changed: function(obj) {
var color = colorSelect.value, // 顏色
memory = memorySelect.value,// 內(nèi)存
number = +numberInput.value, // 數(shù)量
stock = goods[color + '|' + memory]; // 對(duì)應(yīng)顏色的庫存量
if(obj === colorSelect) {
colorInfo.innerHTML = color;
}else if(obj === memorySelect) {
memeryInfo.innerHTML = memory;
}else if(obj === numberInput) {
numberInfo.innerHTML = number;
}
if(!color) {
nextBtn.disabled = true;
nextBtn.innerHTML = "請選擇手機(jī)顏色";
return;
}
if(!memory) {
nextBtn.disabled = true;
nextBtn.innerHTML = "請選擇手機(jī)內(nèi)存";
return;
}
if(!number || (((number - 0) | 0) !== (number - 0))) {
nextBtn.disabled = true;
nextBtn.innerHTML = "請選擇手機(jī)數(shù)量";
return;
}
if( number > stock) {
nextBtn.disabled = true;
nextBtn.innerHTML = "庫存不足";
return;
}
nextBtn.disabled = false;
nextBtn.innerHTML = "加入購物車";
}
};
})();
// 事件函數(shù)
colorSelect.onchange = function() {
mediator.changed(this);
};
memorySelect.onchange = function() {
mediator.changed(this);
};
numberInput.oninput = function() {
mediator.changed(this);
}
中介者模式是迎合迪米特法則的一種實(shí)現(xiàn)。迪米特法則也叫最少知識(shí)原則,是指一個(gè)對(duì)象應(yīng)該盡可能少地了解另外的對(duì)象。避免“城門失火,殃及魚池”。
缺點(diǎn):最大的缺點(diǎn)是系統(tǒng)中會(huì)增加一個(gè)中介對(duì)象,因?yàn)閷?duì)象之間交互的復(fù)雜性,轉(zhuǎn)移成了中介對(duì)象的復(fù)雜性,使得中介者對(duì)象經(jīng)常是巨大的,很難維護(hù)。
一般來說,如果對(duì)象之間的復(fù)雜耦合確實(shí)導(dǎo)致調(diào)用和維護(hù)出現(xiàn)了困難,而且這些耦合度隨項(xiàng)目的變化呈指數(shù)增長,那么我們可以考慮用中介者模式來重構(gòu)代碼。
希望本文所述對(duì)大家學(xué)習(xí)javascript程序設(shè)計(jì)有所幫助。
相關(guān)文章
javascript+xml實(shí)現(xiàn)簡單圖片輪換(只支持IE)
看著許多網(wǎng)站都有廣告自動(dòng)輪換;自己試著寫了一個(gè)圖片輪換,代碼和功能都很簡單,只支持IE的,FF的還要加些東東,需要了解的朋友可以參考下2012-12-12
BootStrap 輪播插件(carousel)支持左右手勢滑動(dòng)的方法(三種)
這篇文章主要介紹了BootStrap 輪播插件(carousel)支持左右手勢滑動(dòng)的方法(三種)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07
利用d3.js力導(dǎo)布局繪制資源拓?fù)鋱D實(shí)例教程
這篇文章主要給大家介紹了關(guān)于如何利用d3.js力導(dǎo)布局繪制資源拓?fù)鋱D的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01
使用變量動(dòng)態(tài)設(shè)置js的屬性名
js的屬性名可以使用變量,例如js對(duì)象object,當(dāng)賦給該對(duì)象屬性的時(shí)候可以采用以下方式,比較實(shí)用,需要的朋友可以看看2014-10-10
JS使用tofixed與round處理數(shù)據(jù)四舍五入的區(qū)別
js中一般使用tofixed與round處理數(shù)據(jù)四舍五入,那么tofixed與round有什么區(qū)別呢?下面小編給大家分享JS使用tofixed與round處理數(shù)據(jù)四舍五入的區(qū)別,需要的朋友參考下吧2017-10-10
基于JavaScript實(shí)現(xiàn)數(shù)值型坐標(biāo)軸刻度計(jì)算算法(echarts的y軸刻度計(jì)算)
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)數(shù)值型坐標(biāo)軸刻度計(jì)算算法(echarts的y軸刻度計(jì)算),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,感興趣的朋友可以參考與一下2022-06-06

