天天看點

JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。

我寫的程式員面試系列文章

Java面試系列-webapp檔案夾和WebContent檔案夾的差別? 程式員面試系列:Spring MVC能響應HTTP請求的原因? Java程式員面試系列-什麼是Java Marker Interface(标記接口) 使用JDK自帶的工具jstack找出造成運作程式死鎖的原因 程式設計面試題:編寫一個會造成資料庫死鎖的應用
JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。

設計模式(Design Pattern)中的橋接模式,有的朋友平時工作可能很少用到。橋接模式的核心在于将抽象部分和它的實作部分分離,使它們都可以獨立的變化。聽起來很抽象,讓我們看一個具體而簡單的例子,通過這個例子一步步的完善來加深對橋接模式的了解。

很多論壇點登入按鈕時,

JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。

周圍背景都會暗下來,這樣可以突出即将彈出的登入框,讓使用者把精力集中在使用者名和密碼的輸入上去。

JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。

很多論壇對于這種背景變暗的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();

})           
JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。

版本1的缺點

每次點選按鈕都會建立一個mask div。當然一般情況下登入按鈕隻會點選一次。但是在面試場景中,面試官可能會把這個問題的讨論引導到其他方向上。如何實作即使多次點選按鈕,也隻會建立一次mask div?于是就有了版本2。

實作版本2

事先建立好一個mask div,放到一個全局變量裡儲存。這種方式有點像單例模式(singleton)的餓漢式單例。

JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。
var mask = document.body.appendChild(document.createElement('div' ) );

$( '#logon_button').click(function(){

     mask.show();

})           
JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。

版本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;

}

}           
JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。

版本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面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。

借助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。

JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。

這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。

要擷取更多Jerry的原創技術文章,請關注公衆号"汪子熙"或者掃描下面二維碼:

JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。
JavaScript面試系列:JavaScript設計模式之橋接模式和懶加載我寫的程式員面試系列文章實作版本1版本1的缺點實作版本2版本2的缺點實作版本3版本3的缺點實作版本4版本4的缺點使用橋接模式的實作版本5這個例子展現了橋接模式的作用。我們通過singleton這個單例化構造器函數,成功将業務邏輯(建立mask div)和單例化這個純技術需求分離開,這樣也滿足了單一職責(single responsibility)的設計理念。