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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

巧用拦截器:高效的扩展点设计

發布時間:2024/4/17 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 巧用拦截器:高效的扩展点设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在設計框架時,需要設計一類擴展點,發現不能簡單地繼承或使用事件來給使用者提供 API。最終使用攔截器模式解決了 API 的設計。

?

擴展點使用場景

該擴展點的使用場景如下:

  • 不能使用繼承;需要在類型的繼承體系外(非被擴展類型的子類)對類型進行擴展。
  • 需要能在基本邏輯的執行前、后擴展新的邏輯,甚至可以使用新的邏輯替換基礎邏輯。
  • 對于性能敏感。由于該基礎邏輯是比較核心的代碼,需要盡量地減少擴展點帶來的額外性能消耗、并盡量少地產生額外的對象。
  • ?

    擴展點設計方案選型


    在框架設計時,擴展點設計主要通過幾種類型的 API 來提供:虛方法、事件、接口。(關于擴展點的設計,詳細的內容,參見:《Framework Design Guidelines 2nd Edition》第六章,擴展性設計。)而最常用、最方便使用者使用的擴展點則是前兩個:虛方法和事件。

    前兩種擴展點設計方案的主要區別在于:

  • 場景:繼承中的虛方法主要是為類型的子類型進行擴展而提供的,而事件則主要是為繼承體系外的類型來擴展繼承體系內的類型的行為而提供的;
  • 控制度:子類對虛方法進行重寫時,可以在基類的基本方法前、后編寫自己的擴展代碼,同時還可以控制是否需要調用基類的方法;而事件要實現這些功能,需要提供邏輯前事件(Invoking)、邏輯后事件(Invoked),并通過類似 CancelEventArgs.IsCancel 屬性等方式來控制是否需要執行基本的邏輯。
  • 性能:虛方法的調用是非常高效的,也不會產生額外的對象。而事件的機制本質是委托列表,會遍歷該列表進行調用,同時需要產生額外的委托對象;其次,由于 .NET 事件的設計中往往要求提供一個從 EventArgs 類型上繼承的事件參數對象,在每次調用都構造并傳遞該對象,這也會產品額外的對象壓力。
  • 可以看出,如果是想設計一類提供給繼承體系外類型進行擴展的擴展點, 虛方法、事件兩類 API 都不合適。那我們只能在第三種方式上想辦法:接口。接口的設計則非常靈活,而其實我上面描述的場景會經常遇到,所以應該提取出一類設計模式。經過一番思考,我發現其實攔截器模式比較適合該場景。攔截器模式本身注重對消息、方法的攔截處理,是一種繼承體系外的擴展方法,并被大量用于 AOP 的實現。在這里采用該模式,我們更加關注其在真正核心方法調用前后的擴展機制、以及核心方法的阻斷機制,以及最終擴展 API 提供的形式。

    ?

    實現


    該模式放到 Rafy 中實現提交時的擴展點后,類圖如下:

    ?

    擴展點使用方法也較簡單,使用者繼承攔截器,編寫相應的擴展邏輯即可:

    有一個細節需要注意:上圖中能看到,方法的第一個參數也是一個自定義的參數類型 SubmitArgs。但是由于攔截器是一種鏈式調用,所以這個類型可以采用值類型;在此方法被大量調用時,相對于事件的擴展機制,沒有大量的冗余對象。

    在啟動時,加入以下代碼就可以把該攔截器添加到保存的攔截器列表中:

    ?

    總結


    攔截器模式實現起來比較簡單,該模式的結構非常類似于 GOF 中的職責鏈模式,只是關注點不同。在使用它作為擴展點時,對于使用者來說也比較易用,而且性能相對于事件機制來說更好,所以可以直接作為一種常用的擴展點設計方案。

    總結

    以上是生活随笔為你收集整理的巧用拦截器:高效的扩展点设计的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。