20190410期
設(shè)計(jì)模式-如何理解中介者模式?
定義: 中介者模式(Mediator),用一個(gè)中介對(duì)象來(lái)封裝一系列的對(duì)象交互。中介者使各對(duì)象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互
把它理解成人人喊打的黑房產(chǎn)中介也沒(méi)啥問(wèn)題...把租戶(hù)與房東解藕了..
現(xiàn)實(shí)中的中介者
中介者也被稱(chēng)為調(diào)停者,我們想象一下機(jī)場(chǎng)的指揮塔,如果沒(méi)有指揮塔的存在,每一架飛機(jī)要和方圓百公里的所有飛機(jī)通信,才能確認(rèn)航線以及飛行情況,現(xiàn)實(shí)中的情況是,每架飛機(jī)只需要跟指揮塔通信,指揮塔作為調(diào)停者,知道每一架飛機(jī)的飛行情況,所以它可以安排所有飛機(jī)的起降時(shí)間,及時(shí)做出航線調(diào)整
代碼中的中介者
假設(shè)我們正在編寫(xiě)一個(gè)實(shí)時(shí)的表單驗(yàn)證的程序,有如下需求
當(dāng)用戶(hù)名未輸入時(shí)輸入密碼將提示先輸入用戶(hù)名
當(dāng)密碼未輸入時(shí)輸入確認(rèn)密碼將提示先輸入密碼
當(dāng)性別未選擇時(shí)輸入年齡將提示先選擇性別
當(dāng)點(diǎn)擊提交按鈕的時(shí)候如果有其它項(xiàng)未項(xiàng)寫(xiě)就提示當(dāng)前項(xiàng)不能為空
我們的實(shí)現(xiàn)偽代碼如下
passwordInput.onchange = function(){ if(!nameInput.value){ return alert('請(qǐng)先輸入用戶(hù)名') } } repeatPasswordInput.onchange = function(){ if(!nameInput.value){ return alert('請(qǐng)先輸入密碼') } } ageInputInput.onchange = function(){ if(!sexInput.value){ return alert('請(qǐng)先選擇性別') } } submit.onclick = function(){ if(!nameInput.value){ return alert('請(qǐng)先輸入用戶(hù)名') } if(!nameInput.value){ return alert('請(qǐng)先輸入密碼') } if(!sexInput.value){ return alert('請(qǐng)先選擇性別') } ajax(...) }
雖然目前順利完成了編碼,但隨之來(lái)的需求改變可能給我們帶來(lái)麻煩,現(xiàn)在這個(gè)驗(yàn)證的節(jié)點(diǎn)還不算多,如果增加到10個(gè)或者更多,它們的關(guān)系可能變的錯(cuò)綜復(fù)雜,現(xiàn)在我們來(lái)引入中介者對(duì)象,所有的節(jié)點(diǎn)驗(yàn)證都只跟中介者通信,這樣一來(lái),無(wú)論是修改還是新增驗(yàn)證節(jié)點(diǎn),我們都只需要改變中介者對(duì)象里的代碼
偽代碼如下
var mediator = (function () { return { changed: function (obj) { if (obj === passwordInput && !nameInput.value) { return alert('請(qǐng)先輸入用戶(hù)名') } if (obj === repeatPasswordInput && !passwordInput.value) { return alert('請(qǐng)先輸入密碼') } if (obj === ageInputInput && !sexInput.value) { return alert('請(qǐng)先選擇性別') } } }})()// 我們只需要通知中介者passwordInput.onchange = function () { mediator.changed(this)}repeatPasswordInput.onchange = function () { mediator.changed(this)}ageInputInput.onchange = function () { mediator.changed(this)}// 后面如果再增加其它節(jié)點(diǎn)驗(yàn)證我們只要需改動(dòng)mediator對(duì)象就好var mediator = (function () { / .... / return { changed: function (obj) { // 增加城市驗(yàn)證 if (obj === homeInputInput && !cityInput.value) { return alert('請(qǐng)先選擇城市') } } }})()
總結(jié)
中介者模式用大白話(huà)翻譯指的就是一個(gè)對(duì)象應(yīng)該盡可能的了解另一個(gè)對(duì)象(類(lèi)似不和陌生人說(shuō)話(huà)),如果對(duì)象之間的耦合性太高,一個(gè)對(duì)象發(fā)生改變之后,難免會(huì)影響到其它的對(duì)象,跟城門(mén)失火,殃及池魚(yú)的道理是一樣的,而在中介者模式里,對(duì)象之間幾乎是不知道彼此存在的,它們只能通過(guò)中介者對(duì)象來(lái)相互影響