Javascript设计模式之中介者模式
前言:菜雞也有夢想,而我的夢想就是進一個真正的互聯網大廠。以前學習的時候沒有系統的整理,從今天開始要保持每周寫博客的習慣,希望自己可以有所成長。為了培養編程思維,決定從設計模式開始寫起。我是通過讀《Javascript設計模式與開發實踐》來學習設計模式,并且將知識點和收獲記錄在博客中。
此文僅記錄本人閱讀《JavaScript設計模式與開發實踐》的知識點與想法,感謝作者曾探大大寫出這么好的一本書。如有冒犯,請聯系本人:markcoder@outlook.com處理,請大家購買正版書籍。
1.中介者模式介紹
中介者模式的作用就是解除對象與對象之間的緊耦合關系。增加一個中介者對象后,所有的相關對象都通過中介者對象來通信,而不是互相引用,所以當一個對象發生改變時,只需要通知中介者對象即可。
改造后
2.代碼示例
這里還是使用書中的例子。
假設我們正在編寫一個手機購買的頁面,在購買流程中,可以選擇手機的顏色以及輸入購買數量,同時頁面中有兩個展示區域,分別向用戶展示剛剛選擇好的顏色和數量。還有一個按鈕動態顯示下一步的操作,我們需要查詢該顏色手機對應的庫存,如果庫存數量少于這次的購買數量,按鈕將被禁用并且顯示庫存不足,反之按鈕可以點擊并且顯示放入購物車。
簡單切一個頁面出來。
2.1 不使用中介者模式
接下來將分別監聽 colorSelect 的 onchange 事件函數和 numberInput 的 oninput 事件函數,然 后在這兩個事件中作出相應處理。
let colorSelect = document.querySelector( '#colorSelect' ), numberInput = document.querySelector( '#numberInput' ), colorInfo = document.querySelector( '#colorInfo' ), numberInfo = document.querySelector( '#numberInfo' ), nextBtn = document.querySelector( '#nextBtn' );const goods = { // 模擬從接口取得手機庫存"red": 3, "blue": 6 };// 監聽顏色選擇器改變 colorSelect.addEventListener('change', () => {let color = colorSelect.value, // 顏色number = numberInput.value, // 數量stock = goods[ color ]; // 該顏色手機對應的當前庫存colorInfo.innerHTML = color;if ( !color ){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機顏色'; return; } if ( ( ( number - 0 ) | 0 ) !== number - 0 ){ // 用戶輸入的購買數量是否為正整數nextBtn.disabled = true; nextBtn.innerHTML = '請輸入正確的購買數量'; return; } if ( number > stock ){ // 當前選擇數量沒有超過庫存量nextBtn.disabled = true; nextBtn.innerHTML = '庫存不足'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購物車'; })// 監聽數量輸入框改變 numberInput.addEventListener('change', () => {let color = colorSelect.value, // 顏色number = numberInput.value, // 數量stock = goods[ color ]; // 該顏色手機對應的當前庫存numberInfo.innerHTML = number;if ( !color ){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機顏色'; return; } if ( ( ( number - 0 ) | 0 ) !== number - 0 ){ // 輸入購買數量是否為正整數nextBtn.disabled = true; nextBtn.innerHTML = '請輸入正確的購買數量'; return; }if ( number > stock ){ // 當前選擇數量沒有超過庫存量nextBtn.disabled = true; nextBtn.innerHTML = '庫存不足'; return ; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購物車'; }) 復制代碼如果這時候,需求增加,又加入了CPU種類,那么又要擴充CPU選擇框的函數,如果刪除了某一種類的選擇,又要深入到每一個函數去修改,非常的麻煩,每個節點對象都是耦合在一起的,改變或者增加任何一個節點對象,都要通知到與其相關的對象。
2.2使用中介者模式改寫
const goods = { // 模擬從接口取得手機庫存"red": 3, "blue": 6 };const mediator = (() => {let colorSelect = document.querySelector( '#colorSelect' ), numberInput = document.querySelector( '#numberInput' ), colorInfo = document.querySelector( '#colorInfo' ), numberInfo = document.querySelector( '#numberInfo' ), nextBtn = document.querySelector( '#nextBtn' );return {changed: function( obj ){ let color = colorSelect.value, // 顏色number = numberInput.value // 數量if ( obj === colorSelect ){ // 如果改變的是選擇顏色下拉框colorInfo.innerHTML = color; }else if ( obj === numberInput ){ // 如果改變的是選擇顏色下拉框numberInfo.innerHTML = number; } if ( !color ){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機顏色'; return; } if ( ( ( number - 0 ) | 0 ) !== number - 0 ){ // 輸入購買數量是否為正整數nextBtn.disabled = true; nextBtn.innerHTML = '請輸入正確的購買數量'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購物車'; }} })();// 事件函數: colorSelect.addEventListener('change', () => {mediator.changed( colorSelect ); }); numberInput.addEventListener('input', () => {mediator.changed( numberInput ); }); 復制代碼可以想象,某天我們又要新增一些跟需求相關的節點,比如內存大小,那我們只需要稍稍改動 mediator 對象即可
新切一個頁面
const goods = { // 模擬從接口取得手機庫存"red": 3, "blue": 6 };const mediator = (() => {let colorSelect = document.querySelector( '#colorSelect' ), memorySelect = document.querySelector( '#memorySelect' ), // 新增內存大小numberInput = document.querySelector( '#numberInput' ), colorInfo = document.querySelector( '#colorInfo' ), numberInfo = document.querySelector( '#numberInfo' ), nextBtn = document.querySelector( '#nextBtn' );return {changed: function( obj ){ let color = colorSelect.value, // 顏色number = numberInput.value, // 數量memory = memorySelect.valueif ( obj === colorSelect ){ // 如果改變的是選擇顏色下拉框colorInfo.innerHTML = color; } else if ( obj === numberInput ){ // 如果改變的是選擇顏色下拉框numberInfo.innerHTML = number; } else if ( obj === memorySelect ){ // 如果改變的是選擇內存大小memoryInfo.innerHTML = memory; }if ( !color ){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機顏色'; return; } if ( !memory ){ // 新增內存大小nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機內存大小'; return; } if ( ( ( number - 0 ) | 0 ) !== number - 0 ){ // 輸入購買數量是否為正整數nextBtn.disabled = true; nextBtn.innerHTML = '請輸入正確的購買數量'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購物車'; }} })();// 事件函數:colorSelect.addEventListener('change', () => {mediator.changed( colorSelect ); }); memorySelect.addEventListener('change', () => {mediator.changed( memorySelect ); }); numberInput.addEventListener('input', () => { // 新增內存大小mediator.changed( numberInput ); }); 復制代碼中介者模式可以非常方便地對模塊或者對象進行解耦,但對象之間并非一定需要解耦。在實 際項目中,模塊或對象之間有一些依賴關系是很正常的。畢竟我們寫程序是為了快速完成項目交 付生產,而不是堆砌模式和過度設計。關鍵就在于如何去衡量對象之間的耦合程度。一般來說, 如果對象之間的復雜耦合確實導致調用和維護出現了困難,而且這些耦合度隨項目的變化呈指數 增長曲線,那我們就可以考慮用中介者模式來重構代碼。
轉載于:https://juejin.im/post/5ce3b8fcf265da1b827a712e
總結
以上是生活随笔為你收集整理的Javascript设计模式之中介者模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: React中的状态管理---Mobx
- 下一篇: 2019-05-21 Java学习日记之