從抽象談起(三):AOP編程和ASP.NET MVC

來源:互聯網
上載者:User

AOP(Aspect oriented programming)面向切面編程。說成切面不容易理解,代碼哪裡有切面?又不是三維物體。概念不管,我們從其思想來理解這個名詞吧。 AOP的主要思想是把相同、相似的並且零散的邏輯抽離出來,統一處理;這樣不僅維護起來方便,也讓代碼更加關注自己本身,清晰明了。

比如我們常見的許可權檢查、日誌記錄、異常處理等都是散亂在系統各個地方,比如發表一篇文章的代碼:

public void Post(Article article){if(currentUser is null)throw new AuthException("您還沒有登入");elseArticleManager.Save(article);}

本來一句話ArticleManager.Save就能搞定的事情,現在要加上if else 還要處理異常,代碼顯得異常難看也難以維護。假如換成

[Authorize]public void Post(Article article){ArticleManager.Save(article);}

用AuthroizeAttribute來處理許可權問題,這樣代碼清晰很多,而且可以複用這個Attribute,這麼好的思想就是AOP思想。
當然Attribute只是一種實現方式,Attribute也是調用Post方法前,通過反射得到Attribute,然後執行其代碼,
平時我們用的最多的AOP就在ASP.NET MVC架構裡,這個AuthorizeAttribute就是MVC內建的。我們可以重寫他的一些方法達到自己想要的功能(比如許可權等級等)。

再舉一個處理異常的例子,如果我們有一個統一的處理異常的邏輯,那麼就可以在邏輯代碼裡不用try/catch,而是直接throw exception,這會讓代碼更加整潔。
(PS:比不是說有了統一處理就再也不用try/catch了,有些異常該吃掉的還是要吃掉,這要看具體的業務需求。另外捕獲不到的異常比如線程裡的要注意catch。)
比如例子:

public void Post(Article article){if(String.IsNullOrEmpty(article.Title)){throw new ArgumentMissException("title");}...ArticleManager.Save(article);}protected override void OnException(ExceptionContext filterContext){//..異常處理代碼}

而只要重寫MVC提供好的OnException方法就能處理所有的異常,或者是展現給方便使用的錯誤介面,或者是發送異常日誌都很方便,而不用在每個地方都寫處理的代碼。
延伸考慮一下,如果統一處理異常資訊,那麼對異常的善後處理的把握就要看異常類的設計和運用了。

另外,再看上面的代碼,如果有多個地方需要Post(Article),但又完全不一致,可是欄位檢查是一致的,那就會造成欄位檢查的代碼重複,這種情況要麼用一個單獨的方法來驗證Article的有效性,然後各個地方調用,要麼就用MVC提供的ModelBinder,這也是通過參數的Attribute來實現的AOP方法;MVC考慮的太周到了,不得不贊。

public void Post([ArticleBinder]Article article){//這裡就不需要再寫關於Article的驗證代碼了ArticleManager.Save(article);}public class ArticleBinderAttribute : CustomModelBinderAttribute{    class ArticleBinder : IModelBinder    {        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)        {//雖然自訂了binder很愜意,但這裡擷取參數值時就沒有用Action的參數那麼舒服了。            var title = controllerContext.RouteData.Values["title"].ToString();            if (string.IsNullOrEmpty(title))            {                throw new ArgumentNullException("title");            }            return new Article            {                Title = title            };        }    }    public override System.Web.Mvc.IModelBinder GetBinder()    {        return new ArticleBinder();    }}

  

運用架構提供的AOP很簡單也很愜意,但我們在用別人的架構時不能只做應用級程式員,我們要領會其思想,掌握其本質,明白其實現。
所幸,MVC是開源的,我們可以看他的原始碼,關注提供AOP的地方。

代碼的設計或者說架構的設計,總是想讓代碼寫起來乾淨利落,松耦合,不拖泥帶水。
所以清晰的設計就是從程式的開始,一步步規劃其運行步驟,並在適當的地方提供一些供使用者處理方法。架構就是把使用者框在自己設定的圈子裡,但又儘可能的給使用者自由。
我們看MVC的大致流程,
1、從輸入Url斷行符號那一刻起,先是通過UrlRouting路由,來判斷使用者訪問哪個Controller/Action;
2、通過controllerfactory擷取具體的controller執行個體,使用者可自訂factory。
3、通過actioninvoke調用action,在調用之前需要先擷取action的filter,這些filter就是AOP的攔截器。使用者都可以自訂各種filter(就是自訂的attribute)。
4、根據執行順序執行action和filter,onactionexecuting、onactionexecuted等。
5、找到action對應的view,使用者可自訂viewenginer。
6、呈現頁面結束。

當出錯的時候invoke的catch調用onexception的使用者的實現。

我本想羅列一些MVC的源碼,但感覺沒必要,有心人自己去下載看吧。如果不清楚的可以加群交流。

就是這樣簡單,AOP的思想是想把和當前邏輯不相干的代碼抽離的一種實現,我們如果追求代碼的美感,就會更加在意整體代碼的設計,AOP通常用於一個系統的外圍搭建處。
只有我們把架子、外圍都搭建的漂亮,代碼寫起來才更美。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.