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