利用AOP重构代码

  AOP是什么?  
  AOP是OOP的延续,Aspect Oriented Programming的缩写,即面向方面编程。AOP是GoF设计模式的延续,设计模式追求的是调用者和被调用者之间的解耦,AOP也是这种目标的一 种实现。  
  案例:在应用程序中,我们经常会对某一段程序做异常处理,或者是把一个方法的调用所消耗的时间体现在日志中,如果我们对每个方法都写具体的实现,我想并不是一件轻松的事情。对于异常处理来讲,其实我们平常编程很少去捕获具体的异常,当然特殊程序除外,例如客户端捕获WCF异常时最好捕获CommunicationException,TimeoutException,Exception。否则一般都会直接捕获Exception,因为很多异常往往是意料之外的异常。对于记录方法调用时间问题,我想也非常麻烦,下面例子简单的展示了记录时间:当你需要对多个方法都需要记录时间时,这些代码往往让人感觉有重构的必要。

Stopwatch sw = new Stopwatch();

   sw.Start();

   //方法执行.....

   sw.Stop();

   WebLog.SquareLog.CommonLogger.Error("取积分广场首页酒店数据用时:"+sw.ElapsedMilliseconds .ToString ()+"毫秒");

上面的记录方法调用用时,如果抽象出来,其实有下列特性:
      1:不是具体访问类的首要或主要功能,访问类主要功能是业务逻辑处理。
      2:具体访问类的主要功能可以独立、区分开来的。
      3:是这个系统的一个纵向切面,涉及多个类、多个类的方法。示意图如下:

aspect:  新的程序结构关注系统的纵向切面,例如这里的异常处理以及方法调用时间记录,这个新的程序结构就是aspect(方面),方面(aspect)应该有以下职责:提供一些必备的功能,对被访问对象实现特有功能,以保证所以方法在被执行时都能正常的执行异常处理或者是其它的功能。

AOP应用范围
      1:Authentication 权限
      2:Error handling 错误处理
      3:logging, tracing, profiling and monitoring 记录跟踪 优化 校准
      ......

AOP具体实现:主要是利用泛型委托来实现AOP思想。但泛型委托有一个局限就是最多支持四个参数,当你的方法超过四个时就不太好应用AOP重构了。我最近分析了有以下三个地方我们可以对代码进行优化:

  第一:普通方法异常处理:ErrorHandler类,实现类参考第二或者是第三。

    客户端调用:

代码string ErrorMethodText="取积分广场首页酒店数据异常:";

           list = ErrorWCFHandler .Invoke<ISearchHotelForSquare, List<HotelGenericInfo>>(cli, proxy => proxy.GetHotelGenericListForSquare(requestInfo).ToList() ); 

  第二:客户端调用WCF的异常处理:ErrorWCFHandler。

    代码:

代码public  class ErrorWCFHandler

    {

       public static void Invoke<TContract>(TContract proxy, Action<TContract> action, string MethodElapsedTimeText, string MethodErrorText)

        {

            Stopwatch sw = new Stopwatch();

            sw.Start();

            try

            {

                action(proxy);

                (proxy as ICommunicationObject).Close();

            }

            catch (CommunicationException ex)

            {

                (proxy as ICommunicationObject).Abort();

                //Handle Exception             

                //throw;

                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }

            catch (TimeoutException ex)

            {

                (proxy as ICommunicationObject).Abort();

                //Handle Exception         

                //throw;

                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }

            catch (Exception ex)

            {

                //Handle Exception        

                //(proxy as ICommunicationObject).Close();      

                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }

            sw.Stop();

WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText + sw.ElapsedMilliseconds.ToString() + "毫秒");

        }

       public static TReturn Invoke<TContract, TReturn>(TContract proxy, Func<TContract, TReturn> func, string MethodElapsedTimeText, string MethodErrorText)

        {

            Stopwatch sw = new Stopwatch();

            sw.Start();

            TReturn returnValue = default(TReturn);

            try

            {

                returnValue = func(proxy);

            }

            catch (CommunicationException ex)

            {

                (proxy as ICommunicationObject).Abort();

                //Handle Exception     

                //throw;

                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }

            catch (TimeoutException ex)

            {

                (proxy as ICommunicationObject).Abort();

                //Handle Exception       

                //throw;

                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }

            catch (Exception ex)

            {

                //Handle Exception  

                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }

            sw.Stop();

WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText + sw.ElapsedMilliseconds.ToString() + "毫秒");

            return returnValue;

        }

    }

    客户端调用:

代码string ComputationTimeText="取积分广场首页酒店数据耗时:";

           string ErrorMethodText="取积分广场首页酒店数据异常:";

           list = ErrorWCFHandler .Invoke<ISearchHotelForSquare, List<HotelGenericInfo>>(cli, proxy => proxy.GetHotelGenericListForSquare(requestInfo).ToList

(),ComputationTimeText ,ErrorMethodText );

  第三:记录方法调用时间,这中间也增加了异常处理:ErrorAndComputationTimeHandler

    代码:

代码 public class ErrorAndComputationTimeHandler

    {

        public static void Invoke<TContract>(TContract proxy, Action<TContract> action, string MethodElapsedTimeText,string MethodErrorText)

        {

            Stopwatch sw = new Stopwatch();

            sw.Start();

            try

            {

                action(proxy);

}

            catch (Exception ex)

            {

                //Handle Exception   

                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

}

            sw.Stop();

WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  + sw.ElapsedMilliseconds.ToString() + "毫秒");

        }

        public static void Invoke<TContract, TContract2>(TContract proxy, TContract2 proxy2, Action<TContract, TContract2> action, string MethodElapsedTimeText,string MethodErrorText)

        {

            Stopwatch sw = new Stopwatch();

            sw.Start();

            try

            {

                action(proxy, proxy2);

}

            catch (Exception ex)

            {

                //Handle Exception   

                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

}

            sw.Stop();

WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  + sw.ElapsedMilliseconds.ToString() + "毫秒");

        }

        public static void Invoke<TContract, TContract2, TContract3>(TContract proxy, TContract2 proxy2, TContract3 proxy3, Action<TContract, TContract2, TContract3> action, string MethodElapsedTimeText,string MethodErrorText)

        {

            Stopwatch sw = new Stopwatch();

            sw.Start();

            try

            {

                action(proxy, proxy2, proxy3);

}

            catch (Exception ex)

            {

                //Handle Exception   

                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

}

            sw.Stop();

WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  + sw.ElapsedMilliseconds.ToString() + "毫秒");

        }

        public static void

时间: 2024-09-27 18:24:15

利用AOP重构代码的相关文章

一起谈.NET技术,利用AOP重构代码

AOP是什么? AOP是OOP的延续,Aspect Oriented Programming的缩写,即面向方面编程.AOP是GoF设计模式的延续,设计模式追求的是调用者和被调用者之间的解耦,AOP也是这种目标的一 种实现. 案例:在应用程序中,我们经常会对某一段程序做异常处理,或者是把一个方法的调用所消耗的时间体现在日志中,如果我们对每个方法都写具体的实现,我想并不是一件轻松的事情.对于异常处理来讲,其实我们平常编程很少去捕获具体的异常,当然特殊程序除外,例如客户端捕获WCF异常时最好捕获Com

利用 aop 追踪 数据库连接池使用情况

问题描述 最近一个项目中使用了apache的dbcp 作数据库连接池,最近程序老发现报连接池耗尽.仔细查了代码,没有找到问题.所以想利用 aop 技术确定一下程序中是否有未释放的连接.想法是 看分配的连接和释放的连接是否对等.定义了两个切入点 1.execution(java.sql.Connection javax.sql.DataSource.getConnection()) 2. execution(void java.sql.Connection.close())程序运行时 第二个切入点

领导重构代码,重构一堆的bug,怎么办 ?

问题描述 领导重构代码,重构一堆的bug,怎么办 ? 本来测试通过领导重构代码,重构一堆的bug,页面都给换了?怎么办 解决方案 领导说什么就是什么,不要自作主张 解决方案二: 重构代码,有bug就修正呗.

Android(Java)利用findbugs进行代码静态检查

本文主要介绍利用java静态代码检查工具findbugs进行代码检查,包括其作用.安装.使用.高级功能(远程review和bug同步). 虽然Android提供了Test Project工程以及instrumentation可以方便的进行单元测试,不过据了解国内Android开发会写自测代码的寥寥无几.那么有没有简单的方法一定程度上保证代码质量呢.Android应用开发大多使用Java,所以对于Java代码检查工具都可以适用,本文介绍其中功能较为强大的findbugs. 1.findbugs作用

重构代码的七段历程

&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp; 你曾去想重构一个很老的模块,但是你只看了一眼就恶心极了.奇怪的函数和类的命名,文档等等,整个模块犹如一个带着脚镣的衣衫褴褛的可怜人,虽然可以走路,但是却让人感到很不舒服.面对这种情况,作为真正的程序员绝对不会去认输的,他们会接受挑战.认真分析,哪怕重写也再所不惜.最终那个模块会被他们重构,就像以前和大家介绍过的那些令人销魂的编程方式中的屠宰式编程一样. 以下是重构代

演化架构和紧急设计: 利用可重用代码,第2部分

简介:在使用 演化架构和紧急设计 前几期描述的技术发现 代码中的紧急设计之后,下一步您需要一 种获取和利用这些设计元素的方法.本文介绍了两种用于获取惯用模式的方法:将模式作为 APIs 进行捕 捉:使用元程序设计方法. 本 系列 的前几期主要关注紧急设计中显而易见的第一步:发现 惯用模式.发现惯用模式之后,您要 用它做什么?该问题的答案就是本期重点,本文属于由多个部分组成的系列文章的第二部分.第 1 部分 -代码与设计的关系探讨- 介绍了一种观点的理论基础,这种观点就是软件中的设计真正是指解决方

利用100行代码动态创建并部署流程

1. 关于Activiti中的BPMN Model 在5.12版本中把各个模块进行了大幅度的划分,值得一提的就是activiti-bpmn-的几个模块(activiti-bpmn-converter.activiti-bpmn-layout.activiti-bpmn-model). activiti-bpmn-model:包含了BPMN2.0规范中部分对应的Java定义(也包括Activiti自己扩展的),描述了一些基本属性.结构: activiti-bpmn-converter:该模块负责对

利用FindBugs减少代码中的bug数学习

FindBugs 作用 开发人员在开发了一部分代码后,可以使用FindBugs进行代码缺陷的检查.提高代码的质量,同时也可以减少测试人员给你报的bug数. 静态分析工具承诺无需开发人员费劲就能找出代码中已有的缺陷.当然,如果有多年的编写经验,就会知道这些承诺并不是一定能兑现. 代码缺陷分类 根据缺陷的性质,大致可以分为下列几类 ·Bad practice  不好的做法·Correctness   可能有不正确·Dodgy code     糟糕的代码·Experimental  实验·Inter

利用setLayoutParams在代码中调整布局(Margin和居中)

MainActivity如下: package cn.testfixmargin; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.RelativeLayout; import and