JavaScript面試系列:JavaScript設計模式之橋接模式和懶載入
我寫的程式設計師面試系列文章
Java面試系列-webapp資料夾和WebContent資料夾的區別?
程式設計師面試系列:Spring MVC能響應HTTP請求的原因?
Java程式設計師面試系列-什麼是Java Marker Interface(標記介面)
JavaScript面試系列:JavaScript設計模式之橋接模式和懶載入
設計模式(Design Pattern)中的橋接模式,有的朋友平時工作可能很少用到。橋接模式的核心在於 將抽象部分和它的實現部分分離,使它們都可以獨立的變化。聽起來很抽象,讓我們看一個具體而簡單的例子,透過這個例子一步步的完善來加深對橋接模式的理解。
很多論壇點登入按鈕時,
周圍背景都會暗下來,這樣可以突出即將彈出的登入框,讓使用者把精力集中在使用者名稱和密碼的輸入上去。
很多論壇對於這種背景變暗的UI實現,是建立了一個HTML原生的div元素,加上一些精心設計過背景顏色的CSS樣式來完成的。
我們下面稱這種div元素為遮罩層div元素,即mask div。
下面討論建立mask div的最優解。
實現版本1
建立一個createMask函式,作為登入按鈕的事件響應函式。每次點選按鈕之後執行該函式。
var createMask = function(){ return document.body.appendChild( document. createElement('div') ); } $(‘#logon_button').click(function(){ var mask = createMask(); mask.show(); })
版本1的缺點
每次點選按鈕都會建立一個mask div。當然一般情況下登入按鈕只會點選一次。但是在面試場景中,面試官可能會把這個問題的討論引導到其他方向上。如何實現即使多次點選按鈕,也只會建立一次mask div?於是就有了版本2。
實現版本2
事先建立好一個mask div,放到一個全域性變數裡儲存。這種方式有點像單例模式(singleton)的餓漢式單例。
var mask = document.body.appendChild(document.createElement('div' ) ); $( '#logon_button').click(function(){ mask.show(); })
版本2的缺點
版本2採用了一個全域性變數儲存事先建立好的mask div。還記得那句話麼?全域性變數是萬惡之源。
另外,假設使用者永遠不點登入按鈕,只是以遊客身份瀏覽網站,那麼這個mask div就白白建立了。
實現版本3
var mask;var createMask = function(){ if(mask) return mask; else{ mask = document,body.appendChild( document.createElement('div') );return mask; } }
版本3的缺點
雖然使用了飽漢式單例模式,避免了mask div在沒有點選登入按鈕的情況下不必要的建立,但還是使用了全域性變數來存放mask div。要記住我們現在是在用JavaScript,因此可以用它提供的強大的閉包特性(closure)來實現不需要全域性變數的飽漢式單例模式。
實現版本4
var createMask = function() { var mask; return function() { return mask || ( mask = document.body.appendChild(document.createElement('div'))); } }();
藉助JavaScript的閉包特性,我們在第二行建立的自由變數(Free variable)只在閉包內部可見,外部消費者感知不到這個變數,因此成為儲存mask div的最佳選擇。看起來這個版本已經很完美了?不,它仍然有可以最佳化的空間,即題目提到的橋接模式。
版本4的缺點
從單一職責原理(Single Responsibility)來衡量版本4,createMask函式里實際包含了兩種不同型別的邏輯:
1. 建立mask div
2. 使該mask div “單例化”
我們下面使用橋接模式將這兩種邏輯分開,來實現最終版本。
使用橋接模式的實現版本5
這個實現包含了三個JavaScript函式。首先看singleton函式。
函式singleton的輸入引數是另一個JavaScript函式(我稱其為原始函式),輸出是一個包裝後的函式,其內部使用閉包,將原始函式第一次執行的結果儲存在閉包內,當包裝後的函式第二次執行時,直接返回閉包內儲存的第一次執行結果。我們可以把singleton函式當成一個構造器,傳入任意一個具有返回值的JavaScript函式,負責生產出具有“單例化”特性的新函式。
var singleton = function(fn){ var result; return function() { return result || ( result = fn.apply(this,arguments)); } }var origin = function(){ return document.body.appendChild(document.createElement('div')); };var createMask = singleton(origin);
然後我們呼叫這個singleton函式,把我們原始的建立mask div的函式origin作為引數傳進去,得到加工後的新函式createMask。
這個例子體現了橋接模式的作用。我們透過singleton這個單例化構造器函式,成功將業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。
要獲取更多Jerry的原創技術文章,請關注公眾號"汪子熙"或者掃描下面二維碼:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2213394/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- javascript設計模式橋接模式JavaScript設計模式橋接
- 設計模式之橋接模式設計模式橋接
- 設計模式之【橋接模式】設計模式橋接
- 設計模式系列 11-- 橋接模式設計模式橋接
- PHP 設計模式之橋接模式PHP設計模式橋接
- 設計模式之橋接設計模式橋接
- Java設計模式之(六)——橋接模式Java設計模式橋接
- Android設計模式之橋接模式Android設計模式橋接
- 我學設計模式 之 橋接模式設計模式橋接
- 設計模式-橋接模式設計模式橋接
- 設計模式:橋接模式設計模式橋接
- C#設計模式系列:橋接模式(Bridge)C#設計模式橋接
- Java設計模式-橋接模式Java設計模式橋接
- 小白設計模式:橋接模式設計模式橋接
- 設計模式(八)——橋接模式設計模式橋接
- 設計模式(十二):橋接模式設計模式橋接
- 設計模式(十三)----結構型模式之橋接模式設計模式橋接
- JAVA設計模式之 橋接模式【Bridge Pattern】Java設計模式橋接
- 跟著GPT學設計模式之橋接模式GPT設計模式橋接
- GoLang設計模式19 - 橋接模式Golang設計模式橋接
- Java設計模式(7)----------橋接模式Java設計模式橋接
- 設計模式 | 橋接模式(bridge)設計模式橋接
- 9.設計模式-橋接模式設計模式橋接
- 極簡設計模式-橋接模式設計模式橋接
- Python設計模式-橋接模式Python設計模式橋接
- 大話設計模式—橋接模式設計模式橋接
- 設計模式(七)橋接設計模式橋接
- JavaScript 設計模式系列 - 觀察者模式JavaScript設計模式
- Javascript設計模式之代理模式JavaScript設計模式
- Javascript設計模式之命令模式JavaScript設計模式
- JavaScript 設計模式之策略模式JavaScript設計模式
- Javascript設計模式之策略模式JavaScript設計模式
- Java進階篇設計模式之四 -----介面卡模式和橋接模式Java設計模式橋接
- javascript設計模式系列一JavaScript設計模式
- 設計模式之旅12--橋接模式設計模式橋接
- 23種設計模式(9)- 橋接模式設計模式橋接
- java設計模式之一 橋接模式Java設計模式橋接
- 設計模式學習-裝飾模式,橋接模式設計模式橋接