摘要:門面模式燜面有兩個作用一是簡化類的接口二是消除類與使用他的業(yè)務(wù)代碼之間的耦合他幾乎是所有庫的核心原則通過建立一些便利方法可以讓復(fù)雜系統(tǒng)變得更加簡單易用燜面模式可以使庫提供的工具更加容易理解燜面可以簡化錯誤記錄或者跟蹤頁面視圖統(tǒng)計數(shù)據(jù)這類這類
門面模式
"燜面",有兩個作用,一是簡化類的接口;二是消除類與使用他的業(yè)務(wù)代碼之間的耦合.他幾乎是所有 JS 庫的核心原則.通過建立一些便利方法可以讓復(fù)雜系統(tǒng)變得更加簡單易用,燜面模式可以使庫提供的工具更加容易理解.
燜面可以簡化錯誤記錄或者跟蹤頁面視圖統(tǒng)計數(shù)據(jù)這類這類常用,重復(fù)性的任務(wù),通過添加一些方法(是對元有一些方法的組合利用),還可以讓對象的功能更完善.
燜面可以簡化復(fù)雜接口,可以在背后為你進(jìn)行錯誤檢查,清除不再需要的大對象,以及用一種簡單方式展現(xiàn)對象功能.
這是一種組織性的模式,可以用來修改類和對象的接口,使其更易使用.
快捷方式圖標(biāo),是在引導(dǎo)用戶至某個地方的接口,如果沒有快捷方式,那些內(nèi)部深層次的文件或者目錄就不太容易查找.
基于 GUI 的 OS 就是計算機(jī)數(shù)據(jù)和功能的一個燜面.每次點擊,拖動或者移動?xùn)|西,實際上是在操作燜面,間接地執(zhí)行一些背后的命令.
這里有個兼容各種瀏覽器的事件監(jiān)聽器例子(之前橋接也有個事件監(jiān)聽器例子,但是現(xiàn)在要涉及 addEvent()函數(shù)的定義:
function addEvent(el, type, fn) { if (window.addEventListener) { el.addEVentListrner(type, fn, false); } else if (window.attachEvent) { el.attachEvent(on + type, fn); } else { el["on" + type] = fn; } }
JS 是一種事件驅(qū)動的語言,addEvent 函數(shù)是一個基本的燜面,每次為一個元素添加事件監(jiān)聽器時都得針對瀏覽器間的差異進(jìn)行檢查而煩惱.
為了盡量提高開發(fā)效率,簡化常見任務(wù),提供兼容每個瀏覽器各自內(nèi)置 JS 函數(shù)實現(xiàn)的共同接口(這樣就會方便許多),誕生了許許多多工具函數(shù)集(比如說 loadash),還有Prototype, jQuery, YUI, Vue, React, Angular 等等第三方 JS 庫.
燜面的一個好處是對函數(shù)的組合--convenience function:
function a(x) { ... } function b(y) { ... } function ab(x, y) { a(x); b(y); }
之所以依然保留前兩個函數(shù),是出于細(xì)粒度和靈活性的考慮.
看起來有點類似于橋接模式連接多個類...不過不能混淆,這里的燜面僅僅是對函數(shù)的組合,沒有涉及到類.
用 DOM 腳本編程經(jīng)常用到的兩個普通事件方法為例:
event.stopPropagation() event.preventDefault()
前者用來中斷事件沿著 DOM 樹向上冒泡傳播,后者是阻止瀏覽器針對一個事件的默認(rèn)行為.比如說防止瀏覽器鏈接點擊跳轉(zhuǎn)新頁面,還可以用來阻止表單的提交.
不同瀏覽器為這兩個功能提供的接口略有差異,所以:
var DED = window.DED || {}; DED.util = { stopPropagation: function (e) { if (ev.stopPropagation) { // W3 interface e.stopPropagation(); } else { // IE"s interface e.cancelBubble = true; } }, preventDefault: function (e) { if (e.preventDefault) { // W3 interface e.preventDefault(); } else { // IE"s interface e.returnValue = false; } }, // our convience method. stopEvent: function (e) { DED.util.stopPropagation(e); DED.util.preventDefault(e); } }
燜面和適配器看起來很像,但是實際上,適配器是一種包裝器,對接口進(jìn)行適配以便在不兼容系統(tǒng)中使用它,而創(chuàng)建燜面元素主要是方便起見,提供一個簡化的接口,并不適合于需要特定接口的系統(tǒng).
設(shè)置 HTML 元素樣式現(xiàn)在要用原生 js一次設(shè)置幾個元素的某個樣式,很合理:
var ele1 = document.getElementById("foo"); ele1.style.color = "#f00"; var ele2 = document.getElementById("foo"); ele2.style.color = "#f00"; var ele3 = document.getElementById("foo"); ele3.style.color = "#f00";
不停地寫 getElementById 并且為每個元素設(shè)置同樣的屬性和數(shù)值肯定就不對,這時候用上燜面,創(chuàng)建一個接口,簡化成批設(shè)置元素樣式的工作.現(xiàn)在我們逆向思維:先想象一下如何最方便地使用該方法,然后再編寫方法源碼本身:
setCSS(["foo"], { position: "absolute", top: "50px", left: "300px" }); function serCSS(el, styles) { for (var prop in styles) { if (el.hasOwnProperty(prop)) continue; setStyle(el, prop, styles[prop]); } }設(shè)計一個事件工具
在處理瀏覽器的開發(fā)問題時,最好創(chuàng)建一些燜面函數(shù),如果要設(shè)計一個大型庫,最好把其中所有的工具元素攏在一起,這樣更好用,訪問起來也簡單.鑒于各種瀏覽器在事件處理方面表現(xiàn)出來的大量差異,開發(fā)一個事件工具很有必要.
要用到單體模式,位于DED.Util 命名空間中,包含著各個靜態(tài)方法,比如說,怎樣獲得事件目標(biāo)元素和事件對象,還有如何處理事件傳播和事件默認(rèn)行為:
DED.Util.Event = { getEvent: function (e) { return e || window.event; }, getTarget: function (e) { return e.target || e.srcElement; }, stopPropagation: function (e) { if (e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; } }, preventDefault: function (e) { if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } }, stopEvent: function (e) { this.stopPropagation(e); this.preventDefault(e); } };燜面模式的適用場合
判斷是否應(yīng)該應(yīng)用燜面模式的關(guān)鍵在于辨認(rèn)那些反復(fù)成組出現(xiàn)的代碼,如果兩個函數(shù)經(jīng)常一塊出現(xiàn),那么或許可以可以考慮寫一個組合式的燜面函數(shù);
在核心工具代碼中使用燜面函數(shù)的另一個目的是應(yīng)對 js 內(nèi)置函數(shù)在不同瀏覽器中的不同表現(xiàn).這樣做并不是因為不能直接使用這些 API,而是因為在處理瀏覽器差異問題時最好的解決辦法是把這些差異抽取到燜面方法中
,比如說addEvent 函數(shù)可以提供一個更一致的接口.
編寫一次組合代碼,然后可以反復(fù)使用,并且提供了一個處理常見問題和任務(wù)的簡化接口,也提供了較高層的功能,降低了對外部代碼的依賴程度,為應(yīng)用系統(tǒng)的開發(fā)增加了一些額外的靈活性.通過使用燜面模式,可以避免與下層子系統(tǒng)緊密耦合,可以對這個系統(tǒng)進(jìn)行修改而不會影響到業(yè)務(wù)代碼.
弊燜面模式經(jīng)常會被濫用,相比一個龐雜的燜面函數(shù),一個更簡單的組成函數(shù)在粒度方面更有吸引力.
適配器它用來在現(xiàn)有接口和不兼容的類之間進(jìn)行適配.使用這種模式的對象叫做包裝器 wrapper,他們是在用一個新的接口包裝另一個對象.在設(shè)計類的時候往往會遇到有些接口不能與現(xiàn)有 API 一同使用的情況,借助于適配器,不用直接修改這些類也能使用它們.現(xiàn)在將考察這類場合,并探討用適配器模連接對象的各種方式.適配器特點
適配器可以被添加到現(xiàn)有代碼中以協(xié)調(diào)兩個不同的接口.如果現(xiàn)有代碼的接口能很好地滿足需要,那么可能沒有必要使用適配器.但是如果現(xiàn)有接口對于手頭的需求來說不夠直觀或者實用,那么可以使用適配器來提供一個更簡潔或者更豐富的接口.
從表面上看,適配器模式很想燜面模式,他們都要對別的對象進(jìn)行包裝并且改變其呈現(xiàn)的接口,差別在于如何改變接口.燜面元素展現(xiàn)的是一個簡化的接口,它并不提供額外的選擇,而且有時候為了方便完成常見任務(wù)他還會做出一些假定;而適配器則要把一個接口轉(zhuǎn)換另一個接口,他并不會濾除某些能力,也不會簡化接口.
適配器可以被實現(xiàn)為不兼容方法調(diào)用之間的一個代碼薄層.如果你有一個居右3個字符串參數(shù)的函數(shù),但是客戶系統(tǒng)擁有的是一個包含3個字符串元素的數(shù)組,那么就可以用一個適配器來銜接二者:
var clientObject = { string1: "foo", string2: "var", string3: "baz" }; function interfaceMedthod(str1, str2, str3) { ... } // in order to pass clientObject-param to interfaceMethod-function, we need 適配器: function clentToInterfaceAdapter(srcObj) { interfaceMethod(srcObj.string1, srcObj.string2, srcObj.string3); } clentToInterfaceAdapter(clientObject);
clientToInterfaceAdapter 函數(shù)的作用就在于對 interfaceMethod 函數(shù)進(jìn)行包裝,并把傳遞給它的參數(shù)轉(zhuǎn)換為后者需要的形式.
適配器適用場合適用于客戶系統(tǒng)期待接口與現(xiàn)有 API 提供的接口不兼容這種場合.它只能用來協(xié)調(diào)語法上的差異問題.適配器所適配的兩個方法執(zhí)行的應(yīng)該是類似的任務(wù),否則的話無法解決問題.
利有助于避免大規(guī)模修改現(xiàn)有業(yè)務(wù)代碼,其工作機(jī)制:用一個新的接口對現(xiàn)有類的接口進(jìn)行包裝,這樣業(yè)務(wù)代碼就無需大動干戈.
弊如果需要徹底重寫代碼,另外適配器也會引入一批不要支持的新工具;
如果現(xiàn)有 API 還未定形或者新接口還沒有定形那么適配器不會一直管用;
所以說適配器有可能是一種不必要的開銷,不必引入.
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/87966.html
摘要:缺陷雖然目前確實能給基于存儲的大數(shù)據(jù)方案帶來進(jìn)一步性能提高,但目前的設(shè)計還是有不少缺陷,主要在體現(xiàn)在幾個方面單點架構(gòu)使得可靠性降低。性能數(shù)據(jù)與分析本篇目錄測試環(huán)境測試數(shù)據(jù)us3vmds基于Go語言開發(fā),自帶了Go的profile功能,通過以下命令,可以在指定地址開啟Go的運行時性能分析HTTP服務(wù):? bin ? us3vmds pprof --open 127.0.0.1 8081 ? ...
摘要:上一篇設(shè)計模式適配器模式介紹了如何將一個類的接口轉(zhuǎn)換成另一個符合期望的接口。這一篇將要介紹需要一個為了簡化接口而改變接口的新模式外觀模式。 上一篇《python設(shè)計模式-適配器模式》介紹了如何將一個類的接口轉(zhuǎn)換成另一個符合期望的接口。這一篇將要介紹需要一個為了簡化接口而改變接口的新模式-外觀模式(Facade-Pattern)。 問題 問題:如果你組裝了一套家庭影院,內(nèi)含播放器、投影...
摘要:改變接口的新模式,為了簡化接口這次帶來的模式為外觀模式,之所以這么稱呼,因為它將一個或多個類復(fù)雜的一切都隱藏起來。 改變接口的新模式,為了簡化接口 這次帶來的模式為外觀模式,之所以這么稱呼,因為它將一個或多個類復(fù)雜的一切都隱藏起來。 我依舊舉生活中例子,現(xiàn)在有些朋友家的液晶電視可能是大尺寸的,或者有用投影儀來看電視,打游戲的。有一天我想用家庭影院系統(tǒng)在家里看一次大片。 ...
過去幾年,我們已經(jīng)看到了一系列關(guān)于系統(tǒng)架構(gòu)的想法,包括:六邊形架構(gòu)(接口與適配器)洋蔥架構(gòu)(Onion Architecture)Screaming ArchitectureDCIBCE這些架構(gòu)有很多共同的點(思想),盡管它們細(xì)節(jié)上有所不區(qū)別,它們都有相同的目標(biāo),那就是關(guān)注點分離(the speration of concerns), 它們都是通過將軟件分層來實現(xiàn)這種分離,每個組件至少有一個用于業(yè)...
閱讀 2633·2021-11-25 09:43
閱讀 2735·2021-11-04 16:09
閱讀 1652·2021-10-12 10:13
閱讀 889·2021-09-29 09:35
閱讀 887·2021-08-03 14:03
閱讀 1781·2019-08-30 15:55
閱讀 2997·2019-08-28 18:14
閱讀 3498·2019-08-26 13:43