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],则对特性进行该特性的处理。
浙公网安备 33010602011771号