2020-3-1 前端達(dá)人
中介者對(duì)象踐行了最少知識(shí)原則,指一個(gè)對(duì)象盡可能少的了解別的對(duì)象,從而盡量減少對(duì)象間耦合程度。這樣各個(gè)對(duì)象只需關(guān)注自身實(shí)現(xiàn)邏輯,對(duì)象間的交互關(guān)系交由中介者對(duì)象來(lái)實(shí)現(xiàn)和維護(hù)。
需求背景:
手機(jī)購(gòu)買(mǎi)頁(yè)面,在購(gòu)買(mǎi)流程中,可以選擇手機(jī)的顏色及輸入購(gòu)買(mǎi)數(shù)量,同時(shí)頁(yè)面有兩個(gè)展示區(qū)域,分別向用戶(hù)展示剛選擇好的顏色和數(shù)量。還有一個(gè)按鈕動(dòng)態(tài)顯示下一步的操作,我們需要查詢(xún)?cè)擃伾謾C(jī)對(duì)應(yīng)的庫(kù)存,如果庫(kù)存數(shù)量少于這次購(gòu)買(mǎi)的數(shù)量,按鈕將被禁用并顯示庫(kù)存不足,反之按鈕可以點(diǎn)擊并顯示放入購(gòu)物車(chē)。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>中介者模式 購(gòu)買(mǎi)商品</title> </head> <body> 選擇顏色: <select id="colorSelect"> <option value="">請(qǐng)選擇</option> <option value="red">紅色</option> <option value="blue">藍(lán)色</option> </select> 輸入購(gòu)買(mǎi)數(shù)量: <input type="text" id="numberInput"> 您選擇了顏色:<div id="colorInfo"></div><br> 您輸入了數(shù)量:<div id="numberInfo"></div><br> <button id="nextBtn" disabled>請(qǐng)選擇手機(jī)顏色和購(gòu)買(mǎi)數(shù)量</button> </body> <script> // 最初級(jí)的寫(xiě)法 var colorSelect = document.getElementById('colorSelect'), numberInput = document.getElementById('numberInput'), colorInfo = document.getElementById('colorInfo'), numberInfo = document.getElementById('numberInfo'), nextBtn = document.getElementById('nextBtn'); var goods = { 'red': 3, 'blue': 6 } colorSelect.onchange = function(){ var color = this.value, number = numberInput.value, stock = goods[color] colorInfo.innerHTML = color; if(!color){ nextBtn.disabled = true; nextBtn.innerHTML = '請(qǐng)選擇手機(jī)顏色'; return; } if( ( (number-0) | 0 ) !== number-0 ){ //用戶(hù)輸入的購(gòu)買(mǎi)數(shù)量是否為正整數(shù) nextBtn.disabled = true; nextBtn.innerHTML = '請(qǐng)輸入正確的購(gòu)買(mǎi)數(shù)量'; return; } if(number > stock){ //當(dāng)前選擇數(shù)量大于庫(kù)存量 nextBtn.disabled = true; nextBtn.innerHTML = '庫(kù)存不足'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購(gòu)物車(chē)'; } numberInput.oninput = function(){ var color = colorSelect.value, number = this.value, stock = goods[color] colorInfo.innerHTML = color; if(!color){ nextBtn.disabled = true; nextBtn.innerHTML = '請(qǐng)選擇手機(jī)顏色'; return; } if( ( (number-0) | 0 ) !== number-0 ){ //用戶(hù)輸入的購(gòu)買(mǎi)數(shù)量是否為正整數(shù) nextBtn.disabled = true; nextBtn.innerHTML = '請(qǐng)輸入正確的購(gòu)買(mǎi)數(shù)量'; return; } if(number > stock){ //當(dāng)前選擇數(shù)量大于庫(kù)存量 nextBtn.disabled = true; nextBtn.innerHTML = '庫(kù)存不足'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購(gòu)物車(chē)'; } </script> </html>
在上個(gè)示例中,對(duì)象間聯(lián)系高度耦合,只是兩個(gè)輸入框還好,但如果有多個(gè)的話,相互聯(lián)系就非常復(fù)雜了,此時(shí)就要考慮用到中介者模式。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>中介者模式 購(gòu)買(mǎi)商品</title> </head> <body> 選擇顏色: <select id="colorSelect"> <option value="">請(qǐng)選擇</option> <option value="red">紅色</option> <option value="blue">藍(lán)色</option> </select> 選擇內(nèi)存: <select id="memorySelect"> <option value="">請(qǐng)選擇</option> <option value="32G">32G</option> <option value="16G">16G</option> </select> 輸入購(gòu)買(mǎi)數(shù)量: <input type="text" id="numberInput"> 您選擇了顏色:<div id="colorInfo"></div><br> 您選擇了內(nèi)存:<div id="memoryInfo"></div><br> 您輸入了數(shù)量:<div id="numberInfo"></div><br> <button id="nextBtn" disabled>請(qǐng)選擇手機(jī)顏色、內(nèi)存和購(gòu)買(mǎi)數(shù)量</button> </body> <script> var goods = { 'red|32G': 3, 'red|16G': 0, 'blue|32G': 1, 'blue|16G': 6 } //引入中介者 var mediator = (function(){ var colorSelect = document.getElementById('colorSelect'), memorySelect = document.getElementById('memorySelect'), numberInput = document.getElementById('numberInput'), colorInfo = document.getElementById('colorInfo'), memoryInfo = document.getElementById('memoryInfo'), numberInfo = document.getElementById('numberInfo'), nextBtn = document.getElementById('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 = '請(qǐng)選擇手機(jī)顏色'; return; } if(!memory){ nextBtn.disabled = true; nextBtn.innerHTML = '請(qǐng)選擇手機(jī)內(nèi)存'; return; } if(!number){ nextBtn.disabled = true; nextBtn.innerHTML = '請(qǐng)?zhí)顚?xiě)手機(jī)數(shù)量'; return; } if( ( (number-0) | 0 ) !== number-0 ){ //用戶(hù)輸入的購(gòu)買(mǎi)數(shù)量是否為正整數(shù) nextBtn.disabled = true; nextBtn.innerHTML = '請(qǐng)輸入正確的購(gòu)買(mǎi)數(shù)量'; return; } if(number > stock){ //當(dāng)前選擇數(shù)量大于庫(kù)存量 nextBtn.disabled = true; nextBtn.innerHTML = '庫(kù)存不足'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購(gòu)物車(chē)'; } } })() colorSelect.onchange = function(){ mediator.changed(this) } memorySelect.onchange = function(){ mediator.changed(this) } numberInput.oninput = function(){ mediator.changed(this) } //以后如果想要再增加選項(xiàng),如手機(jī)CPU之類(lèi)的,只需在中介者對(duì)象里加上相應(yīng)配置即可。 </script> </html>在實(shí)際開(kāi)發(fā)中,還是要注意選擇利弊,中介者對(duì)象因?yàn)榘瑢?duì)象間交互的復(fù)雜性,所以維護(hù)成本可能也會(huì)較高。在實(shí)際開(kāi)發(fā)中,最優(yōu)目的還是要快速完成項(xiàng)目交付,而非過(guò)度設(shè)計(jì)和堆砌模式。有時(shí)對(duì)象間的耦合也是有必要的,只有當(dāng)對(duì)象間復(fù)雜耦合確實(shí)已經(jīng)導(dǎo)致調(diào)用與維護(hù)難以為繼,才考慮用中介者模式。
————————————————
版權(quán)聲明:本文為CSDN博主「一期一會(huì)」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_34832846/article/details/85989945
藍(lán)藍(lán)設(shè)計(jì)的小編 http://tweetduck.com