国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

JavaScript中的AOP編程的基本實(shí)現(xiàn)

瀏覽:69日期:2023-05-31 14:23:37
AOP 簡(jiǎn)介

AOP(面向切面編程)的主要作用是把一些跟核心業(yè)務(wù)邏輯模塊無關(guān)的功能抽離出來,這些跟業(yè)務(wù)邏輯無關(guān)的功能通常包括日志統(tǒng)計(jì)、安全控制、異常處理等。把這些功能抽離出來之后, 再通過“動(dòng)態(tài)織入”的方式摻入業(yè)務(wù)邏輯模塊中。

面向切面編程給我們提供了一個(gè)方法,讓我們可以在不修改目標(biāo)邏輯的情況下,將代碼注入到現(xiàn)有的函數(shù)或?qū)ο笾小?/p>

雖然不是必須的,但注入的代碼意味著具有橫切關(guān)注點(diǎn),比如添加日志功能、調(diào)試元數(shù)據(jù)或其它不太通用的但可以注入額外的行為,而不影響原始代碼的內(nèi)容。

給你舉一個(gè)合適的例子,假設(shè)你已經(jīng)寫好了業(yè)務(wù)邏輯,但是現(xiàn)在你意識(shí)到?jīng)]有添加日志代碼。通常的方法是將日志邏輯集中到一個(gè)新的模塊中,然后逐個(gè)函數(shù)添加日志信息。

然而,如果你可以獲取同一個(gè)日志程序,在你想要記錄的每個(gè)方法執(zhí)行過程中的特定節(jié)點(diǎn),只需一行代碼就可將程序注入,那么這肯定會(huì)給你帶來很多便利。難道不是嗎?

切面、通知和切點(diǎn)(是什么、在何時(shí)、在何地)

為了使上面的定義更形式化一點(diǎn),讓我們以日志程序?yàn)槔榻B有關(guān) AOP 的三個(gè)概念。如果你決定進(jìn)一步研究這個(gè)范式,這些將對(duì)你有所幫助:

切面 (是什么): 這是你想要注入到你的目標(biāo)代碼的 “切面” 或者行為。在我們的上下文環(huán)境(JavaScript)中,這指的是封裝了你想要添加的行為的函數(shù)。 通知 (在何時(shí)): 你希望這個(gè)切面什么時(shí)候執(zhí)行?“通知” 指定了你想要執(zhí)行切面代碼的一些常見的時(shí)刻,比如 “before”、“after”、“around”、“whenThrowing” 等等。反過來,它們指的是與代碼執(zhí)行相關(guān)的時(shí)間點(diǎn)。對(duì)于在代碼執(zhí)行后引用的部分,這個(gè)切面將攔截返回值,并可能在需要時(shí)覆蓋它。 切點(diǎn) (在何地): 他們引用了你想要注入的切面在你的目標(biāo)代碼中的位置。理論上,你可以明確指定在目標(biāo)代碼中的任何位置去執(zhí)行切面代碼。實(shí)際上這并不現(xiàn)實(shí),但你可以潛在地指定,比如:“我的對(duì)象中的所有方法”,或者“僅僅是這一個(gè)特定方法”,或者我們甚至可以使用“所有以 get_ 開頭的方法”之類的內(nèi)容。

有了這些解釋,你會(huì)發(fā)現(xiàn)創(chuàng)建一個(gè)基于 AOP 的庫(kù)來向現(xiàn)有的基于 OOP 的業(yè)務(wù)邏輯(舉個(gè)例子)添加日志邏輯是相對(duì)容易的。你所要做的就是用一個(gè)自定義函數(shù)替換目標(biāo)對(duì)象現(xiàn)有的匹配方法,該自定義函數(shù)會(huì)在適當(dāng)?shù)臅r(shí)間點(diǎn)添加切面邏輯,然后再調(diào)用原有的方法。

基本實(shí)現(xiàn)

因?yàn)槲沂且粋€(gè)視覺學(xué)習(xí)者,所以我認(rèn)為,展示一個(gè)基本的例子說明如何實(shí)現(xiàn)一種 切面 方法來添加基于 AOP 的行為將是個(gè)漫長(zhǎng)的過程。

下面的示例將闡明實(shí)現(xiàn)它有多容易以及它給你的代碼帶來的好處。

`/** 用于獲取一個(gè)對(duì)象中所有方法的幫助函數(shù) */ const getMethods = (obj) => Object.getOwnPropertyNames(Object.getPrototypeOf(obj)).filter(item => typeof obj[item] === ’function’)/** 將原始方法替換為自定義函數(shù),該函數(shù)將在通知指示時(shí)調(diào)用我們的切面 */ function replaceMethod(target, methodName, aspect, advice) { const originalCode = target[methodName] target[methodName] = (...args) => { if(['before', 'around'].includes(advice)) { aspect.apply(target, args) } const returnedValue = originalCode.apply(target, args) if(['after', 'around'].includes(advice)) { aspect.apply(target, args) } if('afterReturning' == advice) { return aspect.apply(target, [returnedValue]) } else { return returnedValue } } }module.exports = { // 導(dǎo)出的主要方法:在需要的時(shí)間和位置將切面注入目標(biāo) inject: function(target, aspect, advice, pointcut, method = null) { if(pointcut == 'method') { if(method != null) { replaceMethod(target, method, aspect, advice)} else { throw new Error('Tryin to add an aspect to a method, but no method specified') } } if(pointcut == 'methods') { const methods = getMethods(target) methods.forEach( m => { replaceMethod(target, m, aspect, advice) }) } } }`

非常簡(jiǎn)單,正如我提到的,上面的代碼并沒有涵蓋所有的用例,但是它應(yīng)該足以涵蓋下一個(gè)示例。

但是在我們往下看之前,注意一下這個(gè) replaceMethod 函數(shù),這就是“魔法”生效的地方。它能夠創(chuàng)建新函數(shù),也可以決定我們何時(shí)調(diào)用我們的切面以及如何處理它的返回值。

接下來說明這個(gè)庫(kù)的用法:

`const AOP = require('./aop.js')class MyBussinessLogic {add(a, b) { console.log('Calling add') return a + b}concat(a, b) { console.log('Calling concat') return a + b}power(a, b) { console.log('Calling power') return a ** b}}const o = new MyBussinessLogic()function loggingAspect(...args) { console.log('== Calling the logger function ==') console.log('Arguments received: ' + args) }function printTypeOfReturnedValueAspect(value) { console.log('Returned type: ' + typeof value) }AOP.inject(o, loggingAspect, 'before', 'methods') AOP.inject(o, printTypeOfReturnedValueAspect, 'afterReturning', 'methods')o.add(2,2) o.concat('hello', 'goodbye') o.power(2, 3)`

這只是一個(gè)包含三個(gè)方法的基本對(duì)象,沒什么特別的。我們想要去注入兩個(gè)通用的切面,一個(gè)用于記錄接收到的屬性,另一個(gè)用于分析他們的返回值并記錄他們的類型。兩個(gè)切面,兩行代碼(并不需要六行代碼)。

這個(gè)示例到這里就結(jié)束了,這里是你將得到的輸出:

https://camo.githubusercontent.com/f18ef187f4acddab8df097c8aa4521d632e17759bc1c0831a22ada934388d7b5/68747470733a2f2f63646e2d696d616765732d312e6d656469756d2e636f6d2f6d61782f323030302f312a394b5a42774f6262714145754a4176314757537279672e706e67

AOP 的優(yōu)點(diǎn)

在知道了 AOP 的概念及用途后,也行你已經(jīng)猜到了為什么人們會(huì)想要使用面向切面編程,不過還是讓我們做一個(gè)快速匯總吧:

封裝橫切關(guān)注點(diǎn)的好方法。我非常喜歡封裝,因?yàn)樗馕吨菀组喿x和維護(hù)可以在整個(gè)項(xiàng)目中重復(fù)使用的代碼。 靈活的邏輯。在注入切面時(shí),圍繞通知和切入點(diǎn)實(shí)現(xiàn)的邏輯可以為你提供很大的靈活性。反之這又有助于你動(dòng)態(tài)地打開和關(guān)閉代碼邏輯的不同切面(有意的雙關(guān))。 跨項(xiàng)目重復(fù)使用切面。你可以將切面視為組件,即可以在任何地方運(yùn)行的小的、解耦的代碼片段。如果你正確地編寫了切面代碼,就可以輕松地在不同的項(xiàng)目中共享它們。AOP 的主要問題

因?yàn)椴⒎敲考露际峭昝赖模@種范式遭到了一些批評(píng)者的反對(duì)。

他們提出的主要問題是,它的主要的優(yōu)勢(shì)實(shí)際上隱藏了代碼邏輯和復(fù)雜性,在不太清楚的情況下可能會(huì)產(chǎn)生副作用。

如果你仔細(xì)想想,他們說的有一定道理,AOP 給了你很多能力,可以將無關(guān)的行為添加到現(xiàn)有的方法中,甚至可以替換它們的整個(gè)邏輯。當(dāng)然,這可能不是引入此范式的確切原因,而且它肯定不是我上面提供的示例的意圖。

然而,它確實(shí)可以讓你去做任何你想做的事情,再加上缺乏對(duì)良好編程實(shí)踐的理解,可能會(huì)導(dǎo)致非常大的混亂。

為了不讓自己聽起來太老套,我轉(zhuǎn)述一下 Uncle Ben 的話:

能力越大,責(zé)任越大

如果你想正確地使用 AOP ,那么就必須理解軟件開發(fā)的最佳實(shí)踐。

在我看來,僅僅因?yàn)槟闶褂眠@個(gè)工具之后可能會(huì)帶來很大的損害,并不足以說明這個(gè)工具就是不好的,因?yàn)樗矔?huì)帶來很多的好處(即你可以將很多常見的邏輯提取到一個(gè)集中的位置,并可以在你需要的任何地方用一行代碼注入它)。對(duì)我來說,這是一個(gè)強(qiáng)大的工具,值得學(xué)習(xí),也絕對(duì)值得使用。

面向切面編程是 OOP 的完美補(bǔ)充,特別是得益于 JavaScript 的動(dòng)態(tài)特性,我們可以非常容易地實(shí)現(xiàn)它(如這里的代碼演示)。它提供了強(qiáng)大的功能,能夠?qū)Υ罅窟壿嬤M(jìn)行模塊化和解耦,以后甚至可以與其他項(xiàng)目共享這些邏輯。

當(dāng)然,如果你不正確地使用它,你會(huì)把事情搞得一團(tuán)糟。但是你絕對(duì)可以利用它來簡(jiǎn)化和清理大量的代碼。這就是我對(duì) AOP 的看法,你呢?你曾經(jīng)聽說過 AOP 嗎?你以前使用過它嗎?請(qǐng)?jiān)谙旅媪粞圆⒎窒砟愕南敕ǎ?/p>

到此這篇關(guān)于JavaScript中的AOP編程的文章就介紹到這了,更多相關(guān)js AOP編程內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 俄罗斯特级毛片 | 另类视频区第一页 | 国产一区二区三区在线观看免费 | 深夜做爰性大片很黄很色视频 | 欧美真人毛片动作视频 | 午夜两性视频免费看 | 高清黄色毛片 | 成人免费一区二区三区在线观看 | 玖草资源在线 | 91精品国| 天天做天天爱夜夜大爽完整 | 97国产成人精品视频 | caoporen在线视频入口 | 亚洲综合久久久 | 草草影院在线观看 | 亚洲一区精品在线 | 她也啪97在线视频 | 久久综合婷婷 | 美女张开双腿让男人桶视频免费 | 91成年人| 久久精品综合 | 国产精品久久久久久久久久直 | 欧美一区二区在线免费观看 | 色综合色狠狠天天久久婷婷基地 | 国产v精品成人免费视频400条 | 成年免费大片黄在线观看一 | 精品久久久久久国产91 | 欧美日韩亚洲高清不卡一区二区三区 | 精品国产网站 | 亚洲欧美卡通动漫丝袜美腿 | 国产精品短视频免费观看 | 91香蕉国产线在线观看免费 | 久久视精品 | 久久国产欧美日韩精品免费 | 一级毛片在线视频 | 未满14周岁啪啪网站 | 中文国产日韩欧美视频 | 久久综合本色宗合一本色 | 久操免费 | 欧美国产合集在线视频 | 久久国产免费 |