zoukankan      html  css  js  c++  java
  • C# 面向切面编程 AOP

    AOP(Aspect Oriented Programming) 面向切面编程

    起源

    引言  http://wayfarer.cnblogs.com/articles/241012.html

    AOP技术基础  https://www.cnblogs.com/wayfarer/articles/241024.html

    .Net平台AOP技术研究 https://www.cnblogs.com/wayfarer/articles/256909.html

    AOP、POP、OOP 区别与联系

    POP面向过程编程:符合逻辑思维,线性的处理问题-----无法应付复杂的系统

    OOP面向对象编程:万物皆对象,对象交互完成功能,功能叠加成模块,模块组成系统,去搭建复杂的大型软件系统
     类----功能点---模块----系统
     类却是会变化的,增加日志/异常/权限/缓存/事务,只能修改类?
     GOF的23种设计模式,应对变化,核心套路是依赖抽象,细节就可以变化
     但是只能替换整个对象,但是没办法把一个类动态改变

    AOP(Aspect):允许开发者动态的修改静态的OO模型,就像现实生活中对象在生命周期中会不断的改变自身。
    AOP是一种编程思想,是OOP思想的补充

    正是因为能够动态的扩展功能,所以在程序设计时就可以有以下好处:
    1 聚焦核心业务逻辑,权限/异常/日志/缓存/事务, 通用功能可以通过AOP方式添加,程序设计简单,
    2 功能动态扩展;集中管理,代码复用;规范化;

    实现AOP的多种方式
    a 静态实现--装饰器/代理模式
    b 动态实现--Remoting/Castle(Emit)
    c 静态织入--PostSharp(收费)--扩展编译工具,生成的加入额外代码
    d 依赖注入容器的AOP扩展(开发)
    e MVC的Filter--特性标记,然后该方法执行前/后就多了逻辑  invoker调用中心--负责反射调用方法--检查特性--有则执行额外逻辑 

    A 装饰器模式实现静态代理-AOP 在方法前后增加自定义的方法

     1     public class Business : IBusiness
     2     {
     3         public virtual void DoSomething()
     4         {
     5             Console.WriteLine("DoSomething");
     6         }
     7     }
     8     public class BusinessAOP : IBusiness
     9     {
    10         public BusinessAOP(IBusiness IBusiness)
    11         {
    12             this._IBusiness = IBusiness;
    13         }
    14         private IBusiness _IBusiness;
    15         public override void DoSomething()
    16         {
    17             BeforeProceed();
    18             this._IBusiness.DoSomething();
    19             AfterProceed();
    20         }
    21         /// <summary>
    22         /// 业务逻辑之前
    23         /// </summary>
    24         /// <param name="user"></param>
    25         private void BeforeProceed()
    26         {
    27             Console.WriteLine("方法执行前");
    28         }
    29         /// <summary>
    30         /// 业务逻辑之后
    31         /// </summary>
    32         /// <param name="user"></param>
    33         private void AfterProceed()
    34         {
    35             Console.WriteLine("方法执行后");
    36         }
    37     }
    38     public interface IBusiness
    39     {
    40         void DoSomething();
    41     }
    42       //前端调用
    43       new BusinessAOP(new Business()).DoSomething();
    View Code

    B 代理模式实现静态代理-AOP 在方法前后增加自定义的方法

     1     public class Business : IBusiness
     2     {
     3         public void DoSomething()
     4         {
     5             Console.WriteLine("DoSomething");
     6         }
     7     }
     8     public class ProxyBusinessAOP : IBusiness
     9     {
    10         private IBusiness _IBusiness=new Business();
    11         public void DoSomething()
    12         {
    13             BeforeProceed();
    14             this._IBusiness.DoSomething();
    15             AfterProceed();
    16         }
    17         /// <summary>
    18         /// 业务逻辑之前
    19         /// </summary>
    20         /// <param name="user"></param>
    21         private void BeforeProceed()
    22         {
    23             Console.WriteLine("方法执行前");
    24         }
    25         /// <summary>
    26         /// 业务逻辑之后
    27         /// </summary>
    28         /// <param name="user"></param>
    29         private void AfterProceed()
    30         {
    31             Console.WriteLine("方法执行后");
    32         }
    33     }
    34     public interface IBusiness
    35     {
    36         void DoSomething();
    37     }
    38     //前端调用
    39     new ProxyBusinessAOP().DoSomething();
    View Code

    C 使用.Net Remoting/RealProxy 实现动态代理-局限在业务类必须是继承自MarshalByRefObject类型

     1     /// <summary>
     2     /// 必须继承自MarshalByRefObject父类,否则无法生成
     3     /// </summary>
     4     public class Business : MarshalByRefObject, IBusiness
     5     {
     6         public void DoSomething()
     7         {
     8             Console.WriteLine("DoSomething");
     9         }
    10     }
    11     /// <summary>
    12     /// 真实代理
    13     /// </summary>
    14     /// <typeparam name="T"></typeparam>
    15     public class MyRealProxy<T> : RealProxy
    16     {
    17         private T tTarget;
    18         public MyRealProxy(T target)
    19             : base(typeof(T))
    20         {
    21             this.tTarget = target;
    22         }
    23 
    24         public override IMessage Invoke(IMessage msg)
    25         {
    26             BeforeProceede(msg);//Log  try-catch
    27 
    28             IMethodCallMessage callMessage = (IMethodCallMessage)msg;
    29             object returnValue = callMessage.MethodBase.Invoke(this.tTarget, callMessage.Args);
    30 
    31             AfterProceede(msg);
    32 
    33             return new ReturnMessage(returnValue, new object[0], 0, null, callMessage);
    34         }
    35         public void BeforeProceede(IMessage msg)
    36         {
    37             Console.WriteLine("方法执行前可以加入的逻辑");
    38         }
    39         public void AfterProceede(IMessage msg)
    40         {
    41             Console.WriteLine("方法执行后可以加入的逻辑");
    42         }
    43     }
    44     /// <summary>
    45     /// 透明代理
    46     /// </summary>
    47     public static class TransparentProxy
    48     {
    49         public static T Create<T>()
    50         {
    51             T instance = Activator.CreateInstance<T>();
    52             MyRealProxy<T> realProxy = new MyRealProxy<T>(instance);
    53             T transparentProxy = (T)realProxy.GetTransparentProxy();
    54             return transparentProxy;
    55         }
    56     }
    57     
    58     public interface IBusiness
    59     {
    60         void DoSomething();
    61     }
    62      //前端调用
    63      IBusiness iBusiness = new Business();
    64      iBusiness.DoSomething();
    65      Console.WriteLine("*********************");
    66      iBusiness = TransparentProxy.Create<Business>();
    67      iBusiness.DoSomething();
    View Code

    D 使用CastleDynamicProxy 实现动态代理-方法必须是虚方法

     1     /// <summary>
     2     /// 使用CastleDynamicProxy 实现动态代理
     3     /// 方法必须是虚方法
     4     /// </summary>
     5     public class CastleProxyAOP
     6     {
     7         public static void Show()
     8         {
     9             
    10             ProxyGenerator generator = new ProxyGenerator();
    11             MyInterceptor interceptor = new MyInterceptor();
    12             Business bus = generator.CreateClassProxy<Business>(interceptor);
    13             bus.DoSomething();
    14             Console.Read();
    15         }
    16         public interface IBusiness
    17         {
    18             void DoSomething();
    19         }
    20 
    21         public class Business : IBusiness
    22         {
    23             /// <summary>
    24             /// 必须带上virtual 否则无效~
    25             /// </summary>
    26             /// <param name="user"></param>
    27             public virtual void DoSomething()
    28             {
    29                 Console.WriteLine("DoSomething");
    30             }
    31         }
    32 
    33         public class MyInterceptor : IInterceptor
    34         {
    35             public void Intercept(IInvocation invocation)
    36             {
    37                 PreProceed(invocation);
    38                 invocation.Proceed();//就是调用原始业务方法
    39                 PostProceed(invocation);
    40             }
    41             public void PreProceed(IInvocation invocation)
    42             {
    43                 Console.WriteLine("方法执行前");
    44             }
    45 
    46             public void PostProceed(IInvocation invocation)
    47             {
    48                 Console.WriteLine("方法执行后");
    49             }
    50         }
    51     }
    View Code
  • 相关阅读:
    titanium开发教程0206创建多行的选择器
    titanium开发教程0210创建的文本字段与嵌入的按钮
    titanium开发教程0209配置文本域和文本区键盘类型
    titanium开发教程0301理解tab group
    titanium开发教程0205创建单行的选择器
    linux shell删除文本每行末尾的单个或者多个空格或者制表符
    R语言中scale函数的用法
    R语言中批量提取当前目录中指定类型的文件
    python中提取包含指定字符的行、提取以指定字符开头、指定字符结尾的行
    python中如何统计文件的行数
  • 原文地址:https://www.cnblogs.com/Dewumu/p/11766633.html
Copyright © 2011-2022 走看看