Java面試系列-webapp文件夾和WebContent文件夾的區別?javascript
程序員面試系列:Spring MVC能響應HTTP請求的緣由?java
Java程序員面試系列-什麼是Java Marker Interface(標記接口)程序員
使用JDK自帶的工具jstack找出形成運行程序死鎖的緣由web
設計模式(Design Pattern)中的橋接模式,有的朋友平時工做可能不多用到。橋接模式的核心在於將抽象部分和它的實現部分分離,使它們均可以獨立的變化。聽起來很抽象,讓咱們看一個具體而簡單的例子,經過這個例子一步步的完善來加深對橋接模式的理解。數據庫
不少論壇點登陸按鈕時,編程
周圍背景都會暗下來,這樣能夠突出即將彈出的登陸框,讓用戶把精力集中在用戶名和密碼的輸入上去。設計模式
不少論壇對於這種背景變暗的UI實現,是建立了一個HTML原生的div元素,加上一些精心設計過背景顏色的CSS樣式來完成的。閉包
咱們下面稱這種div元素爲遮罩層div元素,即mask div。app
下面討論建立mask div的最優解。
建立一個createMask函數,做爲登陸按鈕的事件響應函數。每次點擊按鈕以後執行該函數。
var createMask = function(){ return document.body.appendChild( document. createElement('div') ); } $(‘#logon_button').click(function(){ var mask = createMask(); mask.show(); })
每次點擊按鈕都會建立一個mask div。固然通常狀況下登陸按鈕只會點擊一次。可是在面試場景中,面試官可能會把這個問題的討論引導到其餘方向上。如何實現即便屢次點擊按鈕,也只會建立一次mask div?因而就有了版本2。
事先建立好一個mask div,放到一個全局變量裏保存。這種方式有點像單例模式(singleton)的餓漢式單例。
var mask = document.body.appendChild(document.createElement('div' ) ); $( '#logon_button').click(function(){ mask.show(); })
版本2採用了一個全局變量保存事先建立好的mask div。還記得那句話麼?全局變量是萬惡之源。
另外,假設用戶永遠不點登陸按鈕,只是以遊客身份瀏覽網站,那麼這個mask div就白白建立了。
var mask; var createMask = function(){ if(mask) return mask; else{ mask = document,body.appendChild( document.createElement('div') ); return mask; } }
雖然使用了飽漢式單例模式,避免了mask div在沒有點擊登陸按鈕的狀況下沒必要要的建立,但仍是使用了全局變量來存放mask div。要記住咱們如今是在用JavaScript,所以能夠用它提供的強大的閉包特性(closure)來實現不須要全局變量的飽漢式單例模式。
var createMask = function() { var mask; return function() { return mask || ( mask = document.body.appendChild(document.createElement('div'))); } }();
藉助JavaScript的閉包特性,咱們在第二行建立的自由變量(Free variable)只在閉包內部可見,外部消費者感知不到這個變量,所以成爲存儲mask div的最佳選擇。看起來這個版本已經很完美了?不,它仍然有能夠優化的空間,即題目提到的橋接模式。
從單一職責原理(Single Responsibility)來衡量版本4,createMask函數裏實際包含了兩種不一樣類型的邏輯:
1. 建立mask div
2. 使該mask div 「單例化」
咱們下面使用橋接模式將這兩種邏輯分開,來實現最終版本。
這個實現包含了三個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。
要獲取更多Jerry的原創技術文章,請關注公衆號"汪子熙"或者掃描下面二維碼: