电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

JavaScript中的AOP編程的基本實現

瀏覽:103日期:2023-05-31 14:23:37
AOP 簡介

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

面向切面編程給我們提供了一個方法,讓我們可以在不修改目標邏輯的情況下,將代碼注入到現有的函數或對象中。

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

給你舉一個合適的例子,假設你已經寫好了業務邏輯,但是現在你意識到沒有添加日志代碼。通常的方法是將日志邏輯集中到一個新的模塊中,然后逐個函數添加日志信息。

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

切面、通知和切點(是什么、在何時、在何地)

為了使上面的定義更形式化一點,讓我們以日志程序為例,介紹有關 AOP 的三個概念。如果你決定進一步研究這個范式,這些將對你有所幫助:

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

有了這些解釋,你會發現創建一個基于 AOP 的庫來向現有的基于 OOP 的業務邏輯(舉個例子)添加日志邏輯是相對容易的。你所要做的就是用一個自定義函數替換目標對象現有的匹配方法,該自定義函數會在適當的時間點添加切面邏輯,然后再調用原有的方法。

基本實現

因為我是一個視覺學習者,所以我認為,展示一個基本的例子說明如何實現一種 切面 方法來添加基于 AOP 的行為將是個漫長的過程。

下面的示例將闡明實現它有多容易以及它給你的代碼帶來的好處。

`/** 用于獲取一個對象中所有方法的幫助函數 */ const getMethods = (obj) => Object.getOwnPropertyNames(Object.getPrototypeOf(obj)).filter(item => typeof obj[item] === ’function’)/** 將原始方法替換為自定義函數,該函數將在通知指示時調用我們的切面 */ 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 = { // 導出的主要方法:在需要的時間和位置將切面注入目標 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) }) } } }`

非常簡單,正如我提到的,上面的代碼并沒有涵蓋所有的用例,但是它應該足以涵蓋下一個示例。

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

接下來說明這個庫的用法:

`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)`

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

這個示例到這里就結束了,這里是你將得到的輸出:

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

AOP 的優點

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

封裝橫切關注點的好方法。我非常喜歡封裝,因為它意味著更容易閱讀和維護可以在整個項目中重復使用的代碼。 靈活的邏輯。在注入切面時,圍繞通知和切入點實現的邏輯可以為你提供很大的靈活性。反之這又有助于你動態地打開和關閉代碼邏輯的不同切面(有意的雙關)。 跨項目重復使用切面。你可以將切面視為組件,即可以在任何地方運行的小的、解耦的代碼片段。如果你正確地編寫了切面代碼,就可以輕松地在不同的項目中共享它們。AOP 的主要問題

因為并非每件事都是完美的,這種范式遭到了一些批評者的反對。

他們提出的主要問題是,它的主要的優勢實際上隱藏了代碼邏輯和復雜性,在不太清楚的情況下可能會產生副作用。

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

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

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

能力越大,責任越大

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

在我看來,僅僅因為你使用這個工具之后可能會帶來很大的損害,并不足以說明這個工具就是不好的,因為它也會帶來很多的好處(即你可以將很多常見的邏輯提取到一個集中的位置,并可以在你需要的任何地方用一行代碼注入它)。對我來說,這是一個強大的工具,值得學習,也絕對值得使用。

面向切面編程是 OOP 的完美補充,特別是得益于 JavaScript 的動態特性,我們可以非常容易地實現它(如這里的代碼演示)。它提供了強大的功能,能夠對大量邏輯進行模塊化和解耦,以后甚至可以與其他項目共享這些邏輯。

當然,如果你不正確地使用它,你會把事情搞得一團糟。但是你絕對可以利用它來簡化和清理大量的代碼。這就是我對 AOP 的看法,你呢?你曾經聽說過 AOP 嗎?你以前使用過它嗎?請在下面留言并分享你的想法!

到此這篇關于JavaScript中的AOP編程的文章就介紹到這了,更多相關js AOP編程內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 水篦子|雨篦子|镀锌格栅雨水篦子|不锈钢排水篦子|地下车库水箅子—安平县云航丝网制品厂 | 重庆监控_电子围栏设备安装公司_门禁停车场管理系统-劲浪科技公司 | 千淘酒店差旅平台-中国第一家针对TMC行业的酒店资源供应平台 | 北京浩云律师事务所-企业法律顾问_破产清算等公司法律服务 | 台式低速离心机-脱泡离心机-菌种摇床-常州市万丰仪器制造有限公司 | 骁龙云呼电销防封号系统-axb电销平台-外呼稳定『免费试用』 | 信阳市建筑勘察设计研究院有限公司 | 郑州爱婴幼师学校_专业幼师培训_托育师培训_幼儿教育培训学校 | 智能型高压核相仪-自动开口闪点测试仪-QJ41A电雷管测试仪|上海妙定 | 智能电表|预付费ic卡水电表|nb智能无线远传载波电表-福建百悦信息科技有限公司 | 拉力机-拉力试验机-万能试验机-电子拉力机-拉伸试验机-剥离强度试验机-苏州皖仪实验仪器有限公司 | 赛默飞Thermo veritiproPCR仪|ProFlex3 x 32PCR系统|Countess3细胞计数仪|371|3111二氧化碳培养箱|Mirco17R|Mirco21R离心机|仟诺生物 | 2025第九届世界无人机大会| 苏州西朗门业-欧盟CE|莱茵UL双认证的快速卷帘门品牌厂家 | 众品家具网-家具品牌招商_家具代理加盟_家具门户的首选网络媒体。 | 切铝机-数控切割机-型材切割机-铝型材切割机-【昆山邓氏精密机械有限公司】 | 冲击式破碎机-冲击式制砂机-移动碎石机厂家_青州市富康机械有限公司 | 生物风-销售载体,基因,质粒,ATCC细胞,ATCC菌株等,欢迎购买-百风生物 | 土壤养分检测仪_肥料养分检测仪_土壤水分检测仪-山东莱恩德仪器 大型多片锯,圆木多片锯,方木多片锯,板材多片锯-祥富机械有限公司 | 对照品_中药对照品_标准品_对照药材_「格利普」高纯中药标准品厂家-成都格利普生物科技有限公司 澳门精准正版免费大全,2025新澳门全年免费,新澳天天开奖免费资料大全最新,新澳2025今晚开奖资料,新澳马今天最快最新图库 | 骨密度检测仪_骨密度分析仪_骨密度仪_动脉硬化检测仪专业生产厂家【品源医疗】 | 伊卡洛斯软装首页-电动窗帘,别墅窗帘,定制窗帘,江浙沪1000+别墅窗帘案例 | 扫地车厂家-山西洗地机-太原电动扫地车「大同朔州吕梁晋中忻州长治晋城洗地机」山西锦力环保科技有限公司 | 多功能三相相位伏安表-变压器短路阻抗测试仪-上海妙定电气 | 仿真茅草_人造茅草瓦价格_仿真茅草厂家_仿真茅草供应-深圳市科佰工贸有限公司 | 螺旋丝杆升降机-SWL蜗轮-滚珠丝杆升降机厂家-山东明泰传动机械有限公司 | 实验室装修_实验室设计_实验室规划设计- 上海广建净化工程公司 | 上海办公室装修,写字楼装修—启鸣装饰设计工程有限公司 | 米顿罗计量泵(科普)——韬铭机械| 动物麻醉机-数显脑立体定位仪-北京易则佳科技有限公司 | 活性氧化铝球|氧化铝干燥剂|分子筛干燥剂|氢氧化铝粉-淄博同心材料有限公司 | 粘度计NDJ-5S,粘度计NDJ-8S,越平水分测定仪-上海右一仪器有限公司 | 重庆钣金加工厂家首页-专业定做监控电视墙_操作台 | 上海三信|ph计|酸度计|电导率仪-艾科仪器 | 山东限矩型液力偶合器_液力耦合器易熔塞厂家-淄博市汇川源机械厂 | 仓储笼_金属箱租赁_循环包装_铁网箱_蝴蝶笼租赁_酷龙仓储笼租赁 测试治具|过炉治具|过锡炉治具|工装夹具|测试夹具|允睿自动化设备 | 卓能JOINTLEAN端子连接器厂家-专业提供PCB接线端子|轨道式端子|重载连接器|欧式连接器等电气连接产品和服务 | PCB设计,PCB抄板,电路板打样,PCBA加工-深圳市宏力捷电子有限公司 | 同步带轮_同步带_同步轮_iHF合发齿轮厂家-深圳市合发齿轮机械有限公司 | 房车价格_依维柯/大通/东风御风/福特全顺/江铃图片_云梯搬家车厂家-程力专用汽车股份有限公司 | 汽车水泵_汽车水泵厂家-瑞安市骏迪汽车配件有限公司 |