《2022年面向切面编程[整 .pdf》由会员分享,可在线阅读,更多相关《2022年面向切面编程[整 .pdf(4页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、AOP 问题:面向对象技术很好地解决了软件系统中角色划分的问题。借助于面向对象的分析、设计和实现技术,开发者可以将问题领域的“名词”转换成软件系统中的对象,从而很自然地完成从问题到软件的转换但是,问题领域的某些需求却偏偏不是用这样的“名词”来描述的 我的一个朋友就曾经遇到这样的问题:需要对系统中的某些方法进行日志记录,这种需要记录方法散布在40 多个类中。面对这种需求,应该怎么办呢?最直接的办法就是:创建一个起类(或接口),将日志的功能放在其中,并让所有需要日志功能的类继承这个起类(或接口)如果这个需求是后期提出的需要修改的地方就会分散在40 多个文件(如果是 C十,这个数量还可能加倍)中。这
2、样大的修改量,无疑会增加出错的几率,并且加大系统维护的难度。面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP 实际是 GoF 设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP 可以说也是这种目标的一种实现。是目前软件开发中的一个热点,也是 Spring 框架中的一个重要内容,利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。AOP 是 OOP 的延续。设计模式孜孜不倦追求的是调用者和被调用者之间的解耦。在 S
3、pring 中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的 完成业务逻辑 仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。AOP、OOP 在字面上虽然非常类似,但却是面向不同领域的两种设计思想。OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元 划分。而 AOP 则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果
4、。这两种设计思想在目标上有着本质的差异。上面的陈述可能过于理论化,举个简单的例子,对于“雇员”这样一个业务实体进行封装,自然是 OOP/OOD的任务,我们可以为其建立一个“Employee”类,并将“雇员”相关的属性和行为封装其中。而用AOP 设计思想对“雇员”进行封装将无从谈起。同样,对于“权限检查”这一动作片断进行划分,则是 AOP 的目标领域。而通过 OOD/OOP对一个动作进行封装,则有点不伦不类。换而言之,OOD/OOP面向名词领域,AOP 面向动词领域。应用举例:假设有在一个应用系统中,有一个共享的数据必须被并发同时访问,首先,将这个数据封装在数据对象中,称为Data Class,
5、同时,将有多个访问类,专门用于在同一时刻访问这同一个数据对象。为了完成上述并发访问同一资源的功能,需要引入锁Lock 的概念,也就是说,某个时刻,当有一个访问类访问这个数据对象时,这个数据对象必须上锁Locked,用完后就立即解锁 unLocked,再供其它访问类访问。使用传统的编程习惯,我们会创建一个抽象类,所有的访问类继承这个抽象父类,如下:abstract class Worker名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 4 页 -abstract void locked();abstract void accessDataObject();abstract void
6、 unlocked();缺点:accessDataObject()方法需要有“锁”状态之类的相关代码。变这些行为的时候不影响业务逻辑的代码。那么面向方面编程则是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可面向方面编程和面向对象编程不但不是互相竞争的技术而且彼此还是很好的互补。面向对象编程主要用于为同一对象层次的公用行为建模。它的弱点是将公共行为应用于多个无关对象模型之间。而这恰恰是面向方面编程适合的地方。有了AOP,我们可以定义交叉的关系,并将这些关系应用于跨模块的、彼此不同的对象模型。AOP 同时还可以让我
7、们层次化功能性而不是嵌入功能性,从而使得代码有更好的可读性和易于维护。它会和面向对象编程合作得很好。传统的程序通常表现出一些不能自然地适合单一的程序模块或者是几个紧密相关的程序模块的行为,AOP 将这种行为称为横切,它们跨越了给定编程模型中的典型职责界限。横切行为的实现都是分散的,软件设计师会发现这种行为难以用正常的逻辑来思考、实现和更改。最常见的一些横切行为如下面这些:日志记录,跟踪,优化和监控侧面是一种新的模块化机制,用来描述分散在对象、类或函数 中的横切关注点(crosscutting concern)关注点(concern):对软件工程有意义的小的、可管理的、可描述的软件组成部分,一个
8、关注点通常只同一个特定概念或目标相关联。主关注点(core concern):一个软件最主要的关注点。关注点分离(separation of concerns,SOC):标识、封装和操纵只与特定概念、目标相关联的软件组成部分的能力,即标识、封装和操纵关注点的能力。方法(method):用来描述、设计、实现一个给定关注点的软件构造单位。横切(crosscut):两个关注点相互横切,如果实现它们的方法存在交集。支配性分解(dominant decomposition):将软件分解成模块的主要方式。传统的程序设计语言是以一种线性的文本来描述软件的,只采用一种方式(比如:名师资料总结-精品资料欢迎下载
9、-名师精心整理-第 2 页,共 4 页 -类)将软件分解成模块;这导致某些关注点比较好的被捕捉,容易进一步组合、扩展;但还有一些关注点没有被捕捉,弥散在整个软件内部。支配性分解一般是按主关注点进行模块分解的。横切关注点(crosscutting concerns):在传统的程序设计语言中,除了主关注点可以被支配性分解方式捕捉以外,还有许多没有被支配性分解方式捕捉到的关注点,这些关注点的实现会弥散在整个软件内部,这时这些关注点同主关注点是横切的。侧面(aspect):在支配性分解的基础上,提供的一种辅助的模块化机制,这种新的模块化机制可以捕捉横切关注点。从主关注点 中分离出横切关注点是面向侧面的
10、程序设计的核心概念。分离关注点 使得解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中不再含有针对特定领域问题代码的调用,业务逻辑同特定领域问题的关系通过侧面来封装、维护,这样原本分散在在整个应用程序中的变动就可以很好的管理起来。“面向侧面的程序设计”(aspect-oriented programming)这一术语出现的具体时间已经不可考证了,但该词是由 施乐帕洛阿尔托研究中心的 Chris Maeda首先提出的。术语“横切”(crosscutting)是由 GregorKiczales提出的。编辑例子对于一个信用卡应用程序来说,存款、取款、帐单管理是它的主关注点,日志和持久化将成
11、为横切整个对象结构的横切关注点。连接点(Joinpoint):程序执行过程中的一个点,例如对某个方法的调用或者某个特定异常的抛出都可以称为连接点。通知(Advice):AOP 框架在某个连接点所采取的行为。通知有多种类型,包括“环绕”通知,“前置”通知和“异常”通知等,后文将对通知类型进行讨论。包括Spring.NET在内的很多AOP 框架都把通知建模为拦截器(interceptor),并且会维护一个包围 在连接点周围的拦截器链。切入点(Pointcut):指通知的应用条件,用于确定某个通知要被应用到哪些连接点上。AOP 框架应允许让开发人员指定切入点,例如,可以使用正则表达式来指定一个切入点
12、。引入(Introduction):向目标对象添加方法或字段的行为。Spring.NET允许为任何目标对象引入新的接口。例如,可以利用引入让任何对象在运行期实现IAuditable接口,以简化对象状态变化的跟踪过程。(按:也称为mixin,混入)目标对象(Target object):指包含连接点的对象。也称为被通知或被代理对象。(按:“被通知对象”实际是“被应用了通知的对象”,在译文中,将advised object或 proxied object统称为目标对象,这样更为统一)AOP 代理(AOP proxy):由 AOP 框架在将通知应用于目标对象后创建的对象。在Spring.NET中,A
13、OP 代理是使用IL 代码在运行时创建的动态代理。名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 4 页 -织入(Weaving):将方面进行组装,以创建一个目标对象。织入可以在编译期完成(例如使用Gripper_Loom.NET编译器),也可以在运行时完成。Spring.NET在运行时执行织入。各种通知类型包括:环绕通知(Around Advise):包围(按:即在连接点执行的前、后执行)某个连接点(如方法调用)的通知。这是功能最强大的一种通知。环绕通知允许在方法调用的前后执行自定义行为。它可以决定是让连接点继续执行,还是用自己的返回值或异常来将连接点“短路”。前置通知(Bef
14、ore Advise):在某个连接点执行之前执行,但是不具备阻止连接点继续执行的能力(除非它抛出异常)。异常通知(Throws Advise):当方法(连接点)抛出异常时执行。Spring.NET的异常通知是强类型的(按:Spring.NET用标识接口来定义异常通知,异常通知的处理方法仅需遵循一定的命名规则,可以用具体的异常类型声明其参数,参见12.3.2.3节),所以,可以在代码中直接捕捉某个类型的异常(及其子类异常),不必从Exception转型。后置通知(After returning Advise):在连接点正常执行完成后执行,例如,如果方法正常返回,没有抛出异常时,后置通知就会被执行。名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 4 页 -