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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

AOP(面向切面编程)大概了解一下

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

前言

上一篇在聊MemoryCache的時(shí)候,用到了Autofac提供的攔截器進(jìn)行面向切面編程,很明顯能體會(huì)到其優(yōu)勢(shì),既然涉及到了,那就趁熱打鐵,一起來探探面向切面編程。

正文

1. 概述

在軟件業(yè),AOPAspect Oriented Programming的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運(yùn)行期間動(dòng)態(tài)代理實(shí)現(xiàn)程序功能統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP(面向?qū)ο蟪绦蛟O(shè)計(jì))的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),是函數(shù)式編程的一種衍生范型。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。

---來自百度百科

總結(jié)優(yōu)點(diǎn)

  • 對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,業(yè)務(wù)之間耦合度降低;

  • 提高程序的可重用性,同時(shí)程序更容易維護(hù);

  • 提高開發(fā)效率,不用花大量的時(shí)間在業(yè)務(wù)中增加代碼,還能降低風(fēng)險(xiǎn);

其實(shí)AOP的本質(zhì)就是動(dòng)態(tài)代理,何為動(dòng)態(tài)代理呢?

動(dòng)態(tài)代理就是在程序運(yùn)行時(shí),創(chuàng)建目標(biāo)對(duì)象的代理對(duì)象,并對(duì)目標(biāo)對(duì)象中的方法進(jìn)行功能性增強(qiáng)的一種技術(shù)。通俗一點(diǎn)來說就是在運(yùn)行期間對(duì)方法的攔截,在方法執(zhí)行前后進(jìn)行額外的業(yè)務(wù)處理,從而在不嵌入原有代碼邏輯情況下就能增強(qiáng)被攔截方法的業(yè)務(wù)能力。

理論先到這,一起來看看用代碼怎么實(shí)現(xiàn)吧?

2. 實(shí)踐檢驗(yàn)真理(到底優(yōu)不優(yōu)秀)

先來一個(gè)控制臺(tái)項(xiàng)目,什么都沒有,從頭開始擼代碼,先來看看項(xiàng)目結(jié)構(gòu):

老案例了,還是假裝在進(jìn)行用戶維護(hù),模擬對(duì)用戶進(jìn)行增刪改查。這次就直接上代碼啦啊,根據(jù)項(xiàng)目結(jié)構(gòu)依次看看代碼:

  • 在AopModel中增加User.cs

    public?class?User {public?string?Name?{?get;?set;?}public?int?Age?{?get;?set;?} }
  • 在AopService中增加IUser.cs和User.cs

    IUserService.cs

    public?interface?IUserService {bool?AddUser(User?user); }

    UserService.cs

    public?class?UserService?:?IUserService {public?bool?AddUser(User?user){Console.WriteLine("用戶添加成功");return?true;} }
  • Main方法

    class?Program {static?void?Main(string[]?args){Console.WriteLine("========原始需求=========");User?user?=?new?User?{?Name?=?"Zoe",?Age?=?18?};IUserService?userService?=?new?UserService();//?模擬增加一個(gè)用戶userService.AddUser(user);Console.ReadLine();} }

這樣項(xiàng)目就正常運(yùn)行啦,這個(gè)就不用我截圖了吧,小伙伴都會(huì)吧。

項(xiàng)目運(yùn)行正常,但需要加一個(gè)需求:用戶增加成功之后進(jìn)行郵件發(fā)送通知。

目前有兩種解決方案

  • 直接在增加用戶方法中添加加發(fā)送郵件邏輯(相信很多小伙伴是這樣做的,見效快,還簡(jiǎn)單);

    如果頻繁在增加用戶前或后添加新需求呢,還繼續(xù)加嗎,可能到最后增加用戶的方法變得很復(fù)雜,后期也不好維護(hù);如果要去掉某一個(gè)功能,又得把代碼改回來,作為程序員是不是又要和產(chǎn)品同事搞架啦(文明人,不動(dòng)手);當(dāng)然,如果需求固定,這種方式也不錯(cuò)。

  • 面向切面實(shí)現(xiàn),即在不影響原有代碼邏輯的情況,動(dòng)態(tài)的對(duì)方法進(jìn)行攔截,在方法執(zhí)行前或后添加業(yè)務(wù)即可。

項(xiàng)目中引入AOP(面向切面編程)思想
  • 原始動(dòng)態(tài)代理實(shí)現(xiàn);

    先來加個(gè)代理類,如下:

    using?System; using?System.Collections.Generic; using?System.Reflection; using?System.Text; namespace?Aop {//?繼承DispatchProxypublic?class?MyProxy?:?DispatchProxy{//具體類型public?object?TargetClass?{?get;?set;?}protected?override?object?Invoke(MethodInfo?targetMethod,?object[]?args){Console.WriteLine("增加用戶前執(zhí)行業(yè)務(wù)");//調(diào)用原有方法targetMethod.Invoke(TargetClass,?args);Console.WriteLine("增加用戶后執(zhí)行業(yè)務(wù)");return?true;}} }

    然后在Main函數(shù)直接使用即可,如下:

    class?Program {static?void?Main(string[]?args){//原始需求User?user?=?new?User?{?Name?=?"Zoe",?Age?=?18?};IUserService?userService?=?new?UserService();userService.AddUser(user);Console.WriteLine("========動(dòng)態(tài)代理?實(shí)現(xiàn)新需求=========");//1.?創(chuàng)建代理對(duì)象IUserService?userService1?=?DispatchProxy.Create<IUserService,?MyProxy>();//2.?因?yàn)檎{(diào)用的是實(shí)例方法,需要傳提具體類型((MyProxy)userService1).TargetClass?=?new?UserService();userService1.AddUser(user);Console.ReadLine();} }

    動(dòng)態(tài)代理就實(shí)現(xiàn)需求功能啦,可以在用戶增加前或后都進(jìn)行相關(guān)需求處理,運(yùn)行看效果:

  • 第三方庫(kù)Castle.Core封裝的美滋滋;

    通過上面演示,原生的動(dòng)態(tài)代理實(shí)現(xiàn)面向切面編程顯得相對(duì)麻煩,比如強(qiáng)制轉(zhuǎn)換、傳遞類型等操作;常用的Castle.Core將動(dòng)態(tài)代理進(jìn)一步封裝,使用就相對(duì)方便點(diǎn)啦;這次定義一個(gè)攔截器即可:

    using?Castle.DynamicProxy; using?System; using?System.Collections.Generic; using?System.Text;namespace?Aop {//?自定義攔截器public?class?MyIntercept?:?IInterceptor{public?void?Intercept(IInvocation?invocation){//執(zhí)行原有方法之前Console.WriteLine("增加用戶前執(zhí)行業(yè)務(wù)");//執(zhí)行原有方法invocation.Proceed();//執(zhí)行原有方法之后Console.WriteLine("增加用戶后執(zhí)行業(yè)務(wù)");}} }

    Main函數(shù)中使用攔截器即可,如下:

    using?AopModel; using?AopService; using?Castle.DynamicProxy; using?System; using?System.Reflection; using?System.Reflection.Metadata;namespace?Aop {class?Program{static?void?Main(string[]?args){Console.WriteLine("========原始需求=========");User?user?=?new?User?{?Name?=?"Zoe",?Age?=?18?};IUserService?userService?=?new?UserService();//?模擬增加一個(gè)用戶userService.AddUser(user);Console.WriteLine("========動(dòng)態(tài)代理?實(shí)現(xiàn)新需求=========");//1.?創(chuàng)建代理對(duì)象IUserService?userService1?=?DispatchProxy.Create<IUserService,?MyProxy>();//2.?因?yàn)檎{(diào)用的是實(shí)例方法,需要傳提具體類型((MyProxy)userService1).TargetClass?=?new?UserService();userService1.AddUser(user);Console.WriteLine("=============Castle.Core方式==============");//先實(shí)例化一個(gè)代理類生成器ProxyGenerator?generator?=?new?ProxyGenerator();//通過代理類生成器創(chuàng)建var?u?=?generator.CreateInterfaceProxyWithTarget<IUserService>(new?UserService(),?new?MyIntercept());u.AddUser(user);Console.ReadLine();}} }

    運(yùn)行效果如下:

  • Autofac集成了Castle.Core用著也挺不錯(cuò);

    Autofac已經(jīng)集成了Castle.Core啦,在聊MemoryCache的時(shí)候就已經(jīng)用到,使用比較簡(jiǎn)單,可以通過特性標(biāo)注的方式就可以針對(duì)某個(gè)類或接口的方法進(jìn)行攔截加強(qiáng),詳情請(qǐng)參考這篇文章(因MemoryCache鬧了個(gè)笑話)。

3. 應(yīng)用場(chǎng)景

AOP思想是很優(yōu)秀,但總不能處處都得用吧,需根據(jù)業(yè)務(wù)來評(píng)估是否需要;常用應(yīng)用場(chǎng)景大概有以下幾個(gè):

  • 安全控制:通常在Web開發(fā)的時(shí)候,會(huì)使用過濾器或攔截器進(jìn)行權(quán)限驗(yàn)證,這也是AOP思想的落地;對(duì)于客戶端程序,通過上述演示的幾種方式可以輕松實(shí)現(xiàn)權(quán)限的統(tǒng)一管理和驗(yàn)證;

  • 事務(wù)處理:相信小伙伴都寫過數(shù)據(jù)庫(kù)事務(wù)代碼吧,常規(guī)做法就是在業(yè)務(wù)方法中直接開啟事務(wù),執(zhí)行完成,提交或回滾即可,AOP思想也能很好處理這種情況;

  • 異常處理:統(tǒng)一的異常處理是最好的選擇,除非是特殊的業(yè)務(wù);通常Web有異常過濾器,客戶端程序可以用上述幾種方式;

  • 日志記錄:目前來說日志記錄應(yīng)該是作為系統(tǒng)功能的一部分,AOP統(tǒng)一記錄是不錯(cuò)的選擇;

  • 性能統(tǒng)計(jì):以AOP的思想對(duì)方法進(jìn)行前后監(jiān)控,從而可以分析其執(zhí)行性能;

  • 緩存處理:緩存處理,如上次說到MemoryCache,加上AOP攔截應(yīng)用,系統(tǒng)效率提升不錯(cuò)哦

  • 業(yè)務(wù)輔變主不變:主業(yè)務(wù)變,但會(huì)不定時(shí)增加輔助需求的場(chǎng)景,比如增加用戶,后續(xù)可能在用戶新增成功之后會(huì)增加郵件通知、推送新用戶信息等功能。

源碼地址:https://github.com/zyq025/DotNetCoreStudyDemo

總結(jié)

先暫時(shí)聊這么多吧,瞌睡啦,小伙伴們晚安嘍!!!

一個(gè)被程序搞丑的帥小伙,關(guān)注"Code綜藝圈",跟我一起學(xué)~~~

圖片

總結(jié)

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

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