AOP面向切面编程

  • 面向过程 POP

  符合逻辑思维,线性的处理问题-----无法应付复杂的系统

  • 面向对像 OOP

  万物皆对象,对象交互完成功能,功能叠加成模块,模块组成系统,去搭建复杂的大型软件系统。它的核心是类,但是类是静态的,封闭的,也就是说类在编译时已经确定了它的行为属性,无法在编译完成后动态的对类行为方法增加,如果要增加类的行为方法,就必须修改类,重新编译。

  但同时,在实际项目中,需求是多变的,类也需要根据需求变更,类作为系统的底层核心,它的变化将导致系统的不稳定,因此前人经过经验总结,总结出了设计模式,它使人们可以更加简单方便地复用成功的设计和体系结构,帮助开发人员做出有利于系统复用的选择。设计模式解决特定的设计问题,使面向对象设计更灵活、优雅,最终复用性更好。然而,设计模式虽然给了我们设计的典范与准则,通过最大程度的利用面向对象的特性,诸如利用继承、多态,对责任进行分离、对依赖进行倒置,面向抽象,面向接口,最终设计出灵活、可扩展、可重用的类库、组件,乃至于整个系统的架构。在设计的过程中,通过各种模式体现了对象的行为,暴露的接口,对象间关系,以及对象分别在不同层次中表现出来的形态。然而鉴于对象封装的特殊性,“设计模式”的触角始终在接口与抽象中大做文章,而对于对象内部则无能为力。

  • 面向切面编程 AOP

   把每个页面的通用功能抽取出来,提升到框架层面,把主要精力放在业务逻辑代码的编写,在需要的时候,通过配置把行为注入到类里面,或把行为从类里移除,达到动态改变类的行为目的。如用户验证,异常处理,日志,参数检查,监控等,主种功能称这类的切面,如下图。

 

  • 面向切面编程的好处

    因为可以动态扩展类的功能,面向切面编程有以下好处:

    1. 聚焦核心业务逻辑,权限/异常/日志/缓存/事务, 通用功能可以通过AOP方式添加,程序设计简单

    2.能动态扩展;集中管理,代码复用;规范化

  • 实现AOP的方式

  1. 利用Unity框架实现AOP,以下以一下订单提交类来简要说明Unity的使用。

   a) 引入Unity类库

    

 

    b) 定义类

     订单类

namespace MyAOP.AOP
{
    public class Order
    {
        public int id;
        public DateTime order_date;
        public decimal price;
        public string rem;
    }
}

 

    订单处理接口

namespace MyAOP.AOP
{
    public interface IOrderProcess
    {
        void SubmitOrder(Order order);
    }
}

    订处理单接口实现

namespace MyAOP.AOP
{
    public class OrderProcess : IOrderProcess
    {

        public void SubmitOrder(Order order)
        {
            Console.WriteLine("订单提交成功!");
        }
    }
}

 

     订单参数检查行为

namespace MyAOP.AOP
{
    public class ParameterCheckBehavior : IInterceptionBehavior
    {
        public bool WillExecute { get { return true; } }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("FilterBehavior");
            Order order = input.Inputs[0] as Order;
            if (order.price<0)
                return input.CreateExceptionMethodReturn(new Exception("Price不能小于0"));
            return getNext().Invoke(input, getNext);
        }

    }
}

 

    订单提交入口

namespace MyAOP.AOP
{
    public class OrderAOP
    {
        public static void Show()
        {
            Order order1 = new Order()
            {
                id=1,
                order_date=DateTime.Now,
                price=100,
                rem=""
            };

            Order order2 = new Order()
            {
                id = 2,
                order_date = DateTime.Now,
                price = -100,
                rem = ""
            };
            //配置UnityContainer
            IUnityContainer container = new UnityContainer();
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");
            Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

            UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
            configSection.Configure(container, "MyaopContainer");

            IOrderProcess processor = container.Resolve<IOrderProcess>();
            processor.SubmitOrder(order1);

            IOrderProcess processor2 = container.Resolve<IOrderProcess>();
            processor2.SubmitOrder(order2);
        }
    }

   c) 配置文件

<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
    <!--Microsoft.Practices.Unity.Configuration.UnityConfigurationSection-->
  </configSections>
  <unity>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
    <containers>
      <container name="MyaopContainer">
        <extension type="Interception"/>
        <register type="MyAOP.AOP.IOrderProcess,MyAOP" mapTo="MyAOP.AOP.OrderProcess,MyAOP">
          <interceptor type="InterfaceInterceptor"/>
          <interceptionBehavior type="MyAOP.AOP.ParameterCheckBehavior, MyAOP"/>
        </register>
      </container>
      
    </containers>
  </unity>
</configuration>

   d) 执行结果

 

   我们通过配置文件配置了一个ParameterCheckBehavior参数检测的行为,就可以给我们的订单提交类注册一个参数检测功能,如果我们不再需要这个行为,随时可以在配置文件里移除这个行为,我们还可在后期添加写日志,监控,用户验证等行为,而不需要修改业务类。

  2. 利用特性+反射实现AOP。

   给类配置特性,在调用类时,通过反射获取到特性,如果存在特性,比如[Filter],则对特性进行该特性的处理。

posted on 2020-03-29 16:14  liuzy  阅读(90)  评论(0)    收藏  举报

导航