摘要:橋接模式的核心在于將抽象部分和它的實現部分分離,使它們都可以獨立的變化。看起來這個版本已經很完美了不,它仍然有可以優化的空間,即題目提到的橋接模式。使用橋接模式的實現版本這個實現包含了三個函數。這個例子體現了橋接模式的作用。
我寫的程序員面試系列文章
Java面試系列-webapp文件夾和WebContent文件夾的區別?
程序員面試系列:Spring MVC能響應HTTP請求的原因?
Java程序員面試系列-什么是Java Marker Interface(標記接口)
使用JDK自帶的工具jstack找出造成運行程序死鎖的原因
編程面試題:編寫一個會造成數據庫死鎖的應用
設計模式(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就白白創建了。
實現版本3var 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)來實現不需要全局變量的飽漢式單例模式。
實現版本4var 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的原創技術文章,請關注公眾號"汪子熙"或者掃描下面二維碼:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98590.html
摘要:采用的生成非波拉契數列提供了原生的支持,語法非常有特色,關鍵字后面緊跟一個星號。的詳細介紹參考官網先看如何用這個黑科技重新實現非波拉契樹立的生成。在這個內部,我們定義了一個無限循環,用于計算非波拉契數列。 程序員面試系列 Java面試系列-webapp文件夾和WebContent文件夾的區別? 程序員面試系列:Spring MVC能響應HTTP請求的原因? Java程序員面試系列-什么...
摘要:全網最貼心系列教程和配套代碼歡迎關注個人技術博客。所以我花費了個多月整理了這份教程,一共分成節,每節都有講解,并且準備了配套代碼。奈何深感水平不夠,只有一腔熱情,所以直接開放了教程和源碼。 webpack-demos:全網最貼心 webpack 系列教程和配套代碼 歡迎關注個人技術博客:godbmw.com。每周 1 篇原創技術分享!開源教程(webpack、設計模式)、面試刷題(偏前...
摘要:橋接模式之特權函數特權函數,用一些具有特權的方法作為橋梁以便訪問私有空間,可以回憶一下之前的系列。連續自然數分組,計算最多組的個數將至這個連續自然數分成組使每組相加的值相等。個數組中數字最多的一組有個此時的和為。 本回內容介紹 上一回,聊了適配器模式,圖片預加載,介一回,聊橋接模式(Bridge),跟之前一樣,難度比較小,橋接模式將抽象部分與它的實現部分分離,通過橋接模式聯系彼此,同時...
摘要:我的目標是使本系列成為關于應用程序性能的完整指南。代碼分割就是將應用程序分割成這些延遲加載的塊。總結延遲加載是提高應用程序性能并減少其大小的最佳方法之一。在本系列的下一部分中,我將向您展示如何使用和路由來分割應用程序代碼。 當移動優先(mobile-first)的方式逐漸成為一種標準,而不確定的網絡環境因素應該始終是我們考慮的一點,因此保持讓應用程序快速加載變得越來越困難。在本系列文章...
摘要:函數式編程前端掘金引言面向對象編程一直以來都是中的主導范式。函數式編程是一種強調減少對程序外部狀態產生改變的方式。 JavaScript 函數式編程 - 前端 - 掘金引言 面向對象編程一直以來都是JavaScript中的主導范式。JavaScript作為一門多范式編程語言,然而,近幾年,函數式編程越來越多得受到開發者的青睞。函數式編程是一種強調減少對程序外部狀態產生改變的方式。因此,...
閱讀 3921·2021-11-17 09:33
閱讀 3283·2021-10-08 10:05
閱讀 3111·2021-09-22 15:36
閱讀 1140·2021-09-06 15:02
閱讀 2772·2019-08-29 12:45
閱讀 1590·2019-08-26 13:40
閱讀 3399·2019-08-26 13:37
閱讀 420·2019-08-26 13:37