日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

前端解读面向切面编程(AOP)

發(fā)布時(shí)間:2023/12/2 HTML 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前端解读面向切面编程(AOP) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

面向?qū)ο?OOP)作為經(jīng)典的設(shè)計(jì)范式,對(duì)于我們來說可謂無人不知,還記得我們?nèi)胄衅鹗紩r(shí)那句經(jīng)典的總結(jié)嗎-萬事萬物皆對(duì)象
是的,基于OOP思想封裝、繼承、多態(tài)的特點(diǎn),我們會(huì)自然而然的遵循模塊化、組件化的思維來設(shè)計(jì)開發(fā)應(yīng)用,以到達(dá)易維護(hù)、可擴(kuò)展、高復(fù)用的目的。
既然OOP這么多優(yōu)點(diǎn),那么經(jīng)常被大家提起的面向切面編程(AOP)是什么回事呢,下面我們就一起來看一下。

AOP定義

第一步還是要知道aop是什么,先個(gè)來自維基百科的解釋:

面向側(cè)面的程序設(shè)計(jì)(aspect-oriented programming,AOP,又譯作面向方面的程序設(shè)計(jì)、觀點(diǎn)導(dǎo)向編程、剖面導(dǎo)向程序設(shè)計(jì))是計(jì)算機(jī)科學(xué)中的一個(gè)術(shù)語,指一種程序設(shè)計(jì)范型。
側(cè)面的概念源于對(duì)面向?qū)ο蟮某绦蛟O(shè)計(jì)的改進(jìn),但并不只限于此,它還可以用來改進(jìn)傳統(tǒng)的函數(shù)。

其從主關(guān)注點(diǎn)中分離出橫切關(guān)注點(diǎn)是面向側(cè)面的程序設(shè)計(jì)的核心概念。分離關(guān)注點(diǎn)使得解決特定領(lǐng)域問題的代碼從業(yè)務(wù)邏輯中獨(dú)立出來.
業(yè)務(wù)邏輯的代碼中不再含有針對(duì)特定領(lǐng)域問題代碼的調(diào)用,業(yè)務(wù)邏輯同特定領(lǐng)域問題的關(guān)系通過側(cè)面來封裝、維護(hù). 這樣原本分散在在整個(gè)應(yīng)用程序中的變動(dòng)就可以很好的管理起來。

tip

確實(shí)有點(diǎn)那么不太清晰,有點(diǎn)亂。不過在亂之前,我們可以選能理解的部分先看一下:

  • 側(cè)面(也就是切面) 用來描述分散在對(duì)象、類或函數(shù)中的橫切關(guān)注點(diǎn)
    重點(diǎn)在這,分散在對(duì)象中的橫切關(guān)注點(diǎn),可以猜一下是什么,應(yīng)該就是不同對(duì)象之間公用的部分
  • 側(cè)面的概念源于對(duì)面向?qū)ο蟮某绦蛟O(shè)計(jì)的改進(jìn),它還可以用來改進(jìn)傳統(tǒng)的函數(shù). AOP 顯然不是OOP的替代品,是OOP的一種補(bǔ)充。
  • 從主關(guān)注點(diǎn)中分離出橫切關(guān)注點(diǎn)是面向側(cè)面的程序設(shè)計(jì)的核心概念。
    具體到業(yè)務(wù)項(xiàng)目中來說,主關(guān)注點(diǎn)就是業(yè)務(wù)邏輯了。針對(duì)特定領(lǐng)域問題代碼的調(diào)用,就是AOP要關(guān)注的部分

簡(jiǎn)而言之,AOP是針對(duì)業(yè)務(wù)處理過程中的切面(即非業(yè)務(wù)邏輯部分,例如錯(cuò)誤處理,埋點(diǎn),日志等)進(jìn)行提取.
它所面對(duì)的是處理過程中的某個(gè)步驟或階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果(目的是降低耦合)。
具體到實(shí)現(xiàn)來說就是通過動(dòng)態(tài)的方式將非主關(guān)注點(diǎn)部分插入到主關(guān)注點(diǎn)(一般是業(yè)務(wù)邏輯中)

說了這么多,可能不太明白,還是一起看代碼吧。

埋點(diǎn)場(chǎng)景

很普遍的這么個(gè)場(chǎng)景,需要點(diǎn)擊按鈕之后進(jìn)行信息上報(bào)。 假設(shè)我們有這么個(gè)logger的工具,可以進(jìn)行上報(bào):

const logger = console.log //引入即可使用 logger('按鈕被點(diǎn)擊了')

那么,我們直接擼起來吧:

const doSomething = ()=>{console.log('doSomething') } let clickHandler = ()=>{logger('doSomething之前')// n行代碼 doSomething() logger('doSomething之后')//n 行代碼 }

看起來也沒什么的,簡(jiǎn)單粗暴。
如果有30個(gè)按鈕,每個(gè)業(yè)務(wù)邏輯不同,都需要埋這個(gè)點(diǎn)(假設(shè)打點(diǎn)信息一致)。
我們30個(gè)函數(shù)里面,都要手動(dòng)寫這個(gè)方法的話,這也太坑爹了吧。
主要是與業(yè)務(wù)代碼嚴(yán)重耦合,哪天不小心動(dòng)了點(diǎn)其他內(nèi)容,手抖誤刪了,就gg了。
后續(xù)維護(hù)的時(shí)候,簡(jiǎn)直噩夢(mèng)。
仔細(xì)看一下,這不就是符合AOP的使用前提嗎,那么試試AOP吧。

關(guān)注點(diǎn)劃分

根據(jù)前面提的,可以劃分下關(guān)注點(diǎn)。

主關(guān)注點(diǎn)側(cè)關(guān)注點(diǎn)
業(yè)務(wù)邏輯(doSomething)埋點(diǎn)信息 logger

前面提到AOP關(guān)注的是步驟具體到例子來說其實(shí)就是插入logger的步驟。
插入時(shí)機(jī)無非時(shí)業(yè)務(wù)邏輯執(zhí)行之前或者之后的階段。
具體實(shí)現(xiàn)起來也不那么困難

實(shí)現(xiàn)思路

具體到j(luò)s來說,由于語言本身的特性,天生就具有運(yùn)行時(shí)動(dòng)態(tài)插入邏輯的能力。
重點(diǎn)在于在原函數(shù)上增加其他功能并不改變函數(shù)本身。

畢竟函數(shù)可以接受一切形式的參數(shù),當(dāng)然函數(shù)也不例外了。
當(dāng)傳入一個(gè)函數(shù)的時(shí)候,我們要對(duì)其操作的余地就很大了,
保存原函數(shù),然后利用后續(xù)參數(shù)加上call或apply,就可以達(dá)到我們的目的。
此外為了給函數(shù)都增加一個(gè)屬性,我們?cè)谠蜕喜僮骶托辛恕?/p>

經(jīng)典before或者after的實(shí)現(xiàn)

網(wǎng)上太多類似實(shí)現(xiàn)了,直接看代碼好了:

// action 即為我們的側(cè)關(guān)注點(diǎn),即logger Function.prototype.after = function (action) {//保留當(dāng)前函數(shù),這里this指向運(yùn)行函數(shù)即clickHandlervar func = this;// return 被包裝過的函數(shù),這里就可以執(zhí)行其他功能了。// 并且該方法掛在Function.prototype上,// 被返回的函數(shù)依然具有after屬性,可以鏈?zhǔn)秸{(diào)用return function () {// 原函數(shù)執(zhí)行,這里不考慮異步var result = func.apply(this, arguments);// 執(zhí)行之后的操作action.apply(this,arguments);// 將執(zhí)行結(jié)果返回return result;}; }; // before 實(shí)現(xiàn)類似,只不過執(zhí)行順序差別而已 Function.prototype.before = function (action) {var func = this;return function () {action.apply(this,arguments);return func.apply(this, arguments);}; };

那么我們使用AOP改造之后的代碼就如下了:

const doSomething = ()=>{console.log('doSomething') } let clickHandler = ()=>{// n行代碼 doSomething() //n 行代碼 } clickHandler = clickHandler.before(()=>{logger('doSomething之前') }).after(()=>{logger('doSomething之后') }) clickHandler() // 執(zhí)行結(jié)果和預(yù)期一致

到這里就實(shí)現(xiàn)了面向切面編程,我們的業(yè)務(wù)邏輯里面只管業(yè)務(wù)本身,側(cè)關(guān)注點(diǎn)通過這種方式來動(dòng)態(tài)引入,與主邏輯解耦,更加純凈、易于維護(hù)。

結(jié)束語

到這里,簡(jiǎn)單的AOP就介紹完成了。利用這種模式結(jié)合我們js本身的特性,可以嘗試更多的可能。 例如我們r(jià)eact中常見的HOC、es7的裝飾者模式、HOF等,很多時(shí)候不得不感嘆大牛們思想的精髓,會(huì)讓我們有種頓悟的感覺。本文拋磚引玉,共同學(xué)習(xí)啦,對(duì)自己是總結(jié)和提高,更希望能幫助到需要的小伙伴。更多文章請(qǐng)移步我的博客

參考文章

AllyTeam - 用AOP改善javascript代碼
深入淺出 Javascript Decorators 和 AOP 編程

總結(jié)

以上是生活随笔為你收集整理的前端解读面向切面编程(AOP)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。