摘要:什么是代理模式代理模式,類似于明星的經(jīng)紀(jì)人,想要拜訪明星,需要先通過經(jīng)紀(jì)人的溝通。不同于裝飾器,那種動態(tài)加載一個對象,可以說在代理模式當(dāng)中,代理是早已既定的。又稱單一功能原則,面向?qū)ο笪鍌€基本原則之一。
什么是代理模式
代理模式,類似于明星的經(jīng)紀(jì)人,想要拜訪明星,需要先通過經(jīng)紀(jì)人的溝通。而在JS當(dāng)中,如果想訪問一個類,需要通過另一個類來間接訪問 。不同于裝飾器,那種動態(tài)加載一個對象,可以說在代理模式當(dāng)中,代理是早已既定的。
別人眼中的代理
再拿最常遇到的收快遞這一個社會行為舉例吧。
很早之前,我們收發(fā)快遞都是直接和快遞員交互的,例如:
而現(xiàn)在,加入了代理之后,可以通過第三方替我們接收快遞,即:
這是生活當(dāng)中一個非常常見的例子,可以說代理的存在,大大的便利了“我”這個對象。下面就讓我們在程序中看看代理是如何方便“我”的。
程序做這樣一件事,即根據(jù)不同的快遞類型,來進(jìn)行不同的操作(執(zhí)行不同的函數(shù)),那么在沒有引進(jìn)代理之前,寫法可能是這個樣子。
無代理:
class getDelivery { constructor() { } gets(a) { let fn1 = () => { setTimeout(() => { //some fns of fn1 console.log(`獲取快遞有:${a}`) }, 1000) } let fn2 = () => { setTimeout(() => { //some fns of fn2 console.log(`獲取快遞有:${a}`) }, 2000) } let fn3 = () => { setTimeout(() => { //some fns of fn3 console.log(`獲取快遞有:${a}`) }, 3000) } let deliver = {"中通": fn1, "EMS": fn2, "順豐": fn3}[name]; return deliver(); } } getDelivery.prototype.proxyGets("中通")
定義一個類,上面的gets函數(shù)去判斷不同的快遞類型,然后去執(zhí)行相對應(yīng)的操作。
現(xiàn)在,當(dāng)我們引入代理模式之后,代碼可能是這樣的:
代理:
class getDelivery { constructor() { } gets(a) { console.log(`獲取快遞有:${a}`) } } class proxy extends getDelivery { constructor() { super(); } proxyGets(name) { let fn1 = () => { setTimeout(() => { //some fns of fn1 super.gets("中通快遞") }, 1000) } let fn2 = () => { setTimeout(() => { //some fns of fn2 super.gets("EMS") }, 2000) } let fn3 = () => { setTimeout(() => { //some fns of fn3 super.gets("順豐") }, 3000) } let deliver = {"中通": fn1, "EMS": fn2, "順豐": fn3}[name]; return deliver(); } } proxy.prototype.proxyGets("中通")
(ps:本代碼僅用于代理模式的示例,每次調(diào)用函數(shù)重新聲明fn1等方法是不對的)
ok,這兩種方法都會得到這樣的結(jié)果:
而后者在代碼上還多了一些,但為什么這里還是推薦使用后面這種模式來寫代碼呢?
首先介紹一個面向?qū)ο笤O(shè)計原則,單一職責(zé)原則。
又稱單一功能原則,面向?qū)ο笪鍌€基本原則(SOLID)之一。它規(guī)定一個類應(yīng)該只有一個發(fā)生變化的原因。所謂職責(zé)是指類變化的原因。如果一個類有多于一個的動機被改變,那么這個類就具有多于一個的職責(zé)。而單一職責(zé)原則就是指一個類或者模塊應(yīng)該有且只有一個改變的原因。
而在本例中,我們并不關(guān)心是什么快遞,關(guān)心的只是接到快遞觸發(fā)的結(jié)果,或者說接到快遞后,執(zhí)行的任務(wù)才是getDelivery 這個類的核心,至于中間的過程,應(yīng)該交給專門處理他的類來判別。
第二個原則:開放封閉原則
開放封閉原則(OCP,Open Closed Principle)是所有面向?qū)ο笤瓌t的核心。軟件設(shè)計本身所追求的目標(biāo)就是封裝變化、降低耦合,而開放封閉原則正是對這一目標(biāo)的最直接體現(xiàn)。其他的設(shè)計原則,很多時候是為實現(xiàn)這一目標(biāo)服務(wù)的,例如以Liskov替換原則實現(xiàn)最佳的、正確的繼承層次,就能保證不會違反開放封閉原則。
還以接收快遞為例,比如有一天,接收快遞的形勢變了,或者說,根本不需要判斷是什么快遞,可以隨時接收,那么proxy 這個類其實就沒有用了,此時我們可以直接調(diào)用getDelivery這個類。但是,如果以第一種寫法的話,那就是無路可退了,只能去原對象中去刪掉相對應(yīng)的邏輯。當(dāng)代碼復(fù)雜程度變高的話,高耦合的程序,會讓人非常惡心。
代理模式,在實踐當(dāng)中還可以應(yīng)用于緩存ajax異步數(shù)據(jù),惰性加載等等方面,本文不詳細(xì)講解,僅作拋磚引玉的入門參考。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/91712.html
摘要:注意事項聲明函數(shù)時候處理業(yè)務(wù)邏輯區(qū)分和單例的區(qū)別,配合單例實現(xiàn)初始化構(gòu)造函數(shù)大寫字母開頭推薦注意的成本。簡單工廠模式使用一個類通常為單體來生成實例。 @(書籍閱讀)[JavaScript, 設(shè)計模式] 常見設(shè)計模式 一直對設(shè)計模式不太懂,花了一下午加一晚上的時間,好好的看了看各種設(shè)計模式,并總結(jié)了一下。 設(shè)計模式簡介 設(shè)計模式概念解讀 設(shè)計模式的發(fā)展與在JavaScript中的應(yīng)用 ...
摘要:在中構(gòu)造器的典型特點就是首字母大寫,我們通過原對象代理列表格式去創(chuàng)建對象創(chuàng)建的這個對象我們稱之為代理對象。就是原對象是當(dāng)前的屬性名是代理對象。理解為明星的經(jīng)理人消極怠工原封不動地轉(zhuǎn)告外界的信息給明星本身。但是要注意與是兩個不同的對象。 ES6之Proxy proxy的中文有代理的意思。在其他的程序設(shè)計語言中這個單詞也具有類似的含義。 它是什么 Proxy是一個構(gòu)造器。在js中構(gòu)造器的典...
摘要:最佳實踐使用代理方式實現(xiàn)單例模式,使用一個代理函數(shù)來實現(xiàn)實單例例化原生的代碼摘自設(shè)計模式與開發(fā)實踐下來代理類測試函數(shù)返回版的用實現(xiàn)的單例模式代碼已創(chuàng)建張三李四返回 說明:只要實例化一次,超過一次的實例化過程會返回之前實例化的結(jié)果,而不會在內(nèi)存中再次寫入新的實例對象。----類似于once。 需要遵守的原則:單一職責(zé)的原則,每一個類或者函數(shù)只負(fù)責(zé)一個功能。 最佳實踐:使用代理方式實現(xiàn)單例...
摘要:享元模式通過分析應(yīng)用程序的對象,將其解析為內(nèi)在數(shù)據(jù)和外在數(shù)據(jù),減少對象數(shù)量,從而提高程序的性能。通過這種方式進(jìn)行事件綁定,可以減少事件處理程序的數(shù)量,這種方式叫做事件委托,也是運用了享元模式的原理。事件處理程序是公用的內(nèi)在部分,每個菜單項各 github 全文地址 : YOU-SHOULD-KNOW-JS JavaScript設(shè)計模式之外觀模式 概念 外觀模式:為一組復(fù)雜子系統(tǒng)接口提...
摘要:今天說一下,單一職責(zé)原則。比如,接口的地址本來已經(jīng)很完美了,但是你的是處女座最討厭處女座非要給路由添加幾個以保證后臺數(shù)據(jù)的安全。為了過年,我會選擇使用,因為不知道處女座以后會做出什么傻事來。此時的使用動態(tài)織入后,可以完美的解決處女座。 在設(shè)計模式中,有著幾條視為黃金原則,設(shè)計模式都是圍繞黃金原則,對代碼或者說是架構(gòu)設(shè)計做出一些相應(yīng)的調(diào)整,久而久之,GoF 4人組,發(fā)現(xiàn)其實有些設(shè)計思想可...
閱讀 3740·2021-11-24 09:39
閱讀 2687·2021-11-15 11:37
閱讀 2468·2021-11-11 16:55
閱讀 5972·2021-10-14 09:43
閱讀 3807·2021-10-08 10:05
閱讀 3109·2021-09-13 10:26
閱讀 2416·2021-09-08 09:35
閱讀 3608·2019-08-30 15:55