門面模式是什麼,與其我去用笨拙的語言去解釋,不如看下面這張圖,曾經在網上很火的一張圖片,說的是一位兒子爲他的爸媽設置的電腦桌面。javascript
有了這些起好名字的快捷方式,身爲電腦盲的爸媽就不須要去了解何爲瀏覽器,何爲播放器了,照着指示點就是了。這些快捷方式至關於在用戶和計算機程序之間架起了一座橋樑,不須要每一個用戶都像電影裏的黑客同樣敲着一行行的代碼才能使用計算機的功能。這就是門面模式的意義——把複雜的功能(接口)通過包裝,讓用戶(開發者)能間接地,比較簡單地去使用(調用)它們,簡化使用(開發)的難度。html
門面模式的做用是將複雜的接口進行包裝,變成一個便於使用的接口。在不少的JavaScript庫中都能找到門面模式的應用,例如jQuery,咱們在用jQuery進行事件綁定的時候,簡單的調用bind()
,on()
等方法就能夠了,並不用對不一樣瀏覽器的兼容性問題進行處理,兼容性的處理在jQuery內部已經完成,就是經過門面的思想。java
咱們就以事件綁定爲例,來展示一下門面模式是什麼:segmentfault
// 實現一個通用的,跨多種瀏覽器的時間綁定函數 function addEvent(el, type, fn) { if (window.addEventListener) { el.addEventListener(type, fn, false); } else if (window.attachEvent) { el.attachEvent('on' + type, fn); } else { el['on' + type] = fn; } }
經過能力檢測,對瀏覽器支持的API進行判斷,自動調用有效的事件綁定API來綁定時間。開發者在綁定時間的時候,就不須要寫冗長的判斷代碼,直接專一於業務就好,這是門面模式帶來的最直接的便利。瀏覽器
這裏門面模式的做用是處理瀏覽器的兼容性,門面模式的另外一個做用是對多個函數進行組合管理。app
仍是以事件相關API爲例,事件綁定中還有兩個經常使用的API分別是event.stopPropagation()
和event.preventDefault()
。這兩個API在IE瀏覽器中是不兼容的,在IE中它們分別對應的是event.cancelBubble = true
和event.returnValue = false
。經過門面模式咱們的目標是:
沒有蛀牙~~~
以及:函數
+---------------+ +------------+ +--------------+ +-----------+ |stopPropagation| |cancelBubble| |preventDefault| |returnValue| +---------------+ +------------+ +--------------+ +-----------+ | | | | +--------------------+ +------------------------+ ↓ ↓ +---------------+ +--------------+ |stopPropagation| |preventDefault| +---------------+ +--------------+ | wrapped in | +-------------------------------------------+ ↓ +-----------------------------+ | ╭ stopPropagation | | stopEvent | | ╰ preventDefault | +-----------------------------+
經過代碼事件就是這樣:工具
var eventUtil = { stopPropagation: function(ev) { if (ev.stopPropagation) { ev.stopPropagation(); } else { ev.cancelBubble = true; } }, preventDefault: function(ev) { if (ev.preventDefault) { ev.preventDefault(); } else { ev.returnValue = false; } }, stopEvent: function(ev) { eventUtil.stopPropagation(ev); eventUtil.preventDefault(ev); } }
這樣,在事件綁定函數中,若是須要取消冒泡和默認事件的話,直接調用eventUtil.stopEvent(ev)
便可,該方法將所需的子方法進行了包裝,也處理了兼容性問題。this
結合之前說過的對象建立模式,門面模式能夠應用在模塊之中,經過對私用方法的包裝提供簡化的公用方法,開發者維護模塊時只需修改私用方法就能夠調整公用方法的實現。spa
var orange = (function() { // 私用方法包裝對象 var _privateMethod = { orangeValue: 10, getValue: function() { console.log(this.orangeValue); }, setValue: function(value) { this.orangeValue = value; } } // 返回公用方法 return { setOrangeValue: function(value) { _privateMethod.setValue(value); _privateMethod.getValue(); } } })();
門面模式能提供編寫方式的靈活性,經過對底層子方法的封裝,既簡化了代碼又下降了對底層系統的耦合。在大型系統工具庫的使用中有重要的意義。但在實際項目中仍是要考慮代碼量的輕便性,若是業務只須要一些小粒度的方法的話,就沒有必要使用包裝了不少無用方法的門面函數了,這須要開發者靈活判斷。