面向方面的处理方法(Aspect-Oriented Approach, AOA)是面向方面编程(Aspect Oriented Programming, AOP)和面向方面软件开发(Aspect Oriented Software Development, AOSD)范例的基础,它使得软件开发团队无须重新编译应用程序的源代码就能够对应用程序进行进一步的扩展。本文的目的是利用 IBM Rational Method Compose (RMC) 作为支持平台,将使用面向方面的处理方法(AOA)描述 IBM Rational 统一过程 (Rational Unified Process, RUP) 扩展。
面向方面的程序设计(AOP)是一种正在兴起的建建软件应用程序扩展的方法。AOP 允许您在不影响原始的应用程序源代码的前提下,对现已存在的应用程序进行修改。AOP 主要是针对面向对象(OO)的应用程序的;然而该方法也能够被用于其它类型的应用程序。
IBM® Rational® Unified Process® 简称为 RUP®,是一款被广泛使用的软件开发过程架构,几乎不需要任何指导。RUP 的特性就是一种迭代开发的方法,它基于用例技术在需求管理过程中为高级风险管理提供支持。
IBM Rational Method Composer (RMC) 是一款为建建定制交付过程而设计的新工具。使用 RMC 能够帮助公司创建和管理最适合其业务模型和原则的过程。RMC 还可以作为 RUP 和其他工业标准过程架构的最佳实践指导,例如 IT Infrastructure Library (ISO20000" target="_blank" class="relatedlink">ITIL) 1 ,Project Management Body of Knowledge (PMBOK) 2 和 IBM Rational SUMMIT® Ascendant® 3 。包括内容创作环境在内的 RMC 的大多数特性,可以从 Eclipse Process Framework (EPF) 4 开源代码中获得。
使用面向方面的原因
在工程中使用面向方面的处理方法(AOA)主要基于以下三个重要原因:
面向方面的处理方法(AOA)正是满足了我们对一种记录过程扩展的标准方法的需要。由于大多数公司和项目都要求一种定制的实现过程,于是过程裁剪就成为了常规。项目团队领导者和涉众通常对经典的 RUP 非常了解,但是对定制过程扩展和过程变量并不是十分适应。这种不适应往往是源于抵触方法论和视角,或者是源于贫乏的记录或者冗余的责任。尽管记录过程定制的方法有许多,但是没有一种方法是被大家视作标准化的,而且各家公司或者实现机构必须创建自己的格式来描述扩展。如果公司不能够适当的记录和实现扩展,那么被扩展的过程将变得难以理解和遵守。正如下面将要讨论到的,面向方面的处理方法(AOA)提供了一种捕获过程扩展的模块化方法。
面向方面的处理方法(AOA)有助于工具积极的辅助过程定制。当前,缺乏广泛支持新的强有力的过程创作工具(例如 RMC 和 EPF)的用法指导,从而阻碍了这些工具更加广泛的应用。与此相关的是,缺乏一种记录过程定制的标准方法 5 ,从而阻碍了项目的实现。正如下面将要讨论到的,面向方面的程序设计(AOP)是一种在开发社区中被普遍接受的标准。面向方面的处理方法(AOA)的实现通过普通的过程工程学工具来实现,有可能在那些裁剪过程和那些制定过程之间搭建起技巧和接受程度的桥梁。
面向方面的处理方法(AOA)的原则同过程创作工具高度的兼容。扩展机制,例如 RMC 可变性和后面将要描述的过程贡献,贯彻一些在面向方面的程序设计(AOP)中所采用的相同的原则。例如,如同在 AOP 中一样,RMC 允许您局部化过程变化和扩展,并且无须改变现已存在的交付过程就能够应用它们。
面向方面的处理方法(AOA)概述
AOA 的原则非常简单,并且适用于各种不同的情况。这种方法处理了软件程序设计中广泛存在的横剖问题。
面向方面的程序设计(AOP)范例
与面向方面的处理方法(AOA)不同,目前在程序设计中被广泛采用的模块设计方法将一个应用程序分解为不同的部分——例如组件、模型、类、方法等——这样做最小化了特定关注或者大量关注的功能性交叠和封装实现。从这点上来讲,关注可以是从狭义定义的业务或者系统问题(例如:“取钱”或者“显示用户信息”)到兴趣和焦点的区域(例如:“安全”和“审核”)中的任何事务。不幸的是,将关注清晰的划分到模块中并不总是可行的,这是因为其他的关注有可能会将这种划分横刀切断。举例来说,“取钱”的“安全”和“日志”就是一个典型例子,如下面的表1所示:
表 1:在这个模块设计业务方法的例子中,分别涉及到“安全”和“日志”的编程代码中的“取钱”交缠。
void moveMone y (Account from, Account to, float amount) {if (!getRequestingUser().isAuthorized(OPERATION_WITHDRAW)) { throw new SecurityException(MSG_NO_RIGHT_WITHDRAW_MONEY)}Transaction trn = database.startTransaction();try { from.withdraw ( amount); to.deposit ( amount); trn.commit; logger.logOperation(OPERATION_WITHDRAW, from, to, amount);} catch (DatabaseException e) { trn.rollback();} |
所显示的三个分别的关注——“取钱”、“安全性”和“日志记录”——在这个相对简单的方法中已经表现得十分复杂了。如果关注不再被应用到应用程序中的其他地方的化,这种分离的缺乏也就不会成为什么大的问题;但是,“安全性”和“日志记录”在许多业务方法中都会被用到,它们就是所谓的与单一业务逻辑关注相对应的“横剖关注”。
面向方面的程序设计(AOP)将代码分割到不同的模块之中,这些模块就被称为“aspects”(方面)。方面代码也被称作“建议”。当规则也就是“连接点”为真的时候,建议实现。连接点被封装在被称作“pointcuts(横切点)”的可以计量的扩展(查询)之中。
尽管这一简短的总结为您提供了面向方面的程序设计(AOP)的基本语义学,但是要想全面理解这方面知识的话,我建议您参考相关的文章或者书籍。在本文最后,我列出了一些相关的资源。
现在,我将解释面向方面的程序设计(AOP)的语法,并且讨论 AOP 如何能够被应用到过程域中。
面向方面的程序设计(AOP)语法
最初的和最受欢迎的 AOP 实现——AspectJ——使用语法描述了横切点,如下面的图1所示:
图 1:AspectJ 使用语法来描述横切点
Pointcut Designator
在面向方面的程序设计(AOP)中,许多事件类型能够触发一个建议的实现。事件,例如方法或者构造器调用,类或者对象初始化,以及异常,这些都是有效的 AOP 触发器。为了区别事件的类型,AOP 使用 Primitive横切点 Designators (PPDs)。在上面的例子中,“实现”指示者只激活和使用“签名”的方法的实时实现相关的连接点。
签名
在方法调用期间,签名声明了被传递的参数。
关键字
关键字总是等同于“pointcut”。
Access Specifier
Access Specifier 声明了访问一个函数或者方法的级别。
定义过程扩展的一个被提议的语法
上述用于描述横切点的方法已经被证明是有效的,但是目前并没有一种类似的方法可以用来描述过程横切点。我将讨论造成这种缺乏的个中原因,并且在后面的 “RMC 愿望列表”一节中提供一种可能的解决方案。如果您对 AOP 的实际和实践应用程序十分感兴趣的话,您可能希望继续下去。对于狂热的求知者来说,我现在就将提供用于描述过程横切点 的被提议语法的概述,这些可能会在今后通过过程创作和制定工具被实现。
下面的表2中所显示的语法并不是一个工业标准,而是我自己试图提供的一个不需加以说明的符号:
表 2:笔者提议的描述过程横切点的语法
pointcut RUP_Element_set processExtension(): trigger (RUP_Element_Template),
where: | processExtension() | 横切点名称 | RUP_Element | 来自 RUP 元模型的一个元素 | RUP_Element_set | RUP_Element 元素的集合 | pointcutName | 任意的横切点名称 | trigger | 横切点指定者 | RUP_Element_Trmplate | 过程元素模板 |
“RUP_Element”表现了 RUP 元模型的一个元素,而“RUP_element_set”表现了一个元素集。Process-pointcut 指示者根据程序设计域的不同而不同。在其他选项中,pointcut 指示者可能包括“initial_step”、“initial_task”、“initial_iteration”、“input_to”、“final_step”、“final_task”、“final_iteration”、“output_from”、“output_is”、“where_used”和“where_declared”。
我将在本文后面关于使用 RMC 实现 AOA 的讨论中阐明“RUP_Element”、“RUP_Element_set”和“RUP_Element_Mask”的含义。
过程扩展定义模板
过程扩展定义模板提供了另一种以 AO 术语描述过程扩展的方法。我将使用下面表3所显示的模板,提供如何将 AOP 概念应用到 RUP 定制中的若个例子:
表 3:扩展定义模板
概念 | 实现 | Concern(关注点) | <定义一个关注。一个关注就是一个简单的过程扩展用例,例如“A RUP PM Role has inadequate responsibilities”、“A program director wants tighter control over projects”或者“Insufficient vendor communication” >
<提供一个对关注和被提议的解决方案的简短的描述 > | Join Point(连接点)(s) | <提供一个对新的或者更新的过程元素横切过程情况的简要总结 >
<提供一个连接点的列表 > | Pointcut(衡切点)(可选) | <使用过程横切点定义语法来定义合并连接点的横切点 > | Aspect(方面) | <勾画一种在 RMC 中分组过程方面的方法。该方法通常将使用一种 RUP/RMC 扩展技术(更多详细内容请参见本文后面的“RMC 过程扩展”小节 >
< 提供关于 RMC 方法的包装元素,这些元素包含方面的实现 > | Advice(建议) | <选项一:撰写方面的完整实现。如果需要更强大的实现工具,就要以本地格式有效的链接到文档 >
<选项二:提供一个方面实现的轮廓。简要的描述新的和扩展的内容元素。方面的详细实现将被延期到 RMC >
<选项三:在 RMC 中提供到方面实现的 URL > |
这个模板能够在现实的过程定制和裁剪项目中被用作描述过程扩展。模板自身就是一种 RUP 指导,它必须被包括在扩展的过程描述中。
当变化必须发生在过程中的许多点上的时候,就必须制作过程描述的多个部分,此时您将看到使用面向方面的处理方法(AOA)的最大好处。然而,您应当使用过程扩展模板来描述所有潜在的过程变化,包括那些目标是过程描述中的一个单独位置而非横切的变化。如果遵循这个建议,过程工程团队成员和使用一个扩展过程的项目团队就可能从暗示声明的一致性中得到好处。
在解释过基本的 AOP 概念之后,我将讨论您如何能够将它们应用到一个 RUP 定制中。
面向方面的程序设计(AOP)的概念和例子
下列 AOP 的例子使用普通的程序设计术语,包括“程序”、“系统”和“模块”。我将突出被提议的概念,例如“过程”、“行为”和“任务”,它们能够被用作在 RUP 中扩展过程方法学。
横切关注
“横切关注”是一个程序(过程)中的一个方面(部分),它影响其他的方面,并且不能从系统(过程、行为、任务)中被完全独立出来。将一个新的方面插入到程序(过程)中,情况也是如此。
日志记录是 AOP 的一个合乎规范的例子,这主要是因为它影响了大量重要的应用程序方法。
AOP 例子:
下面的图2显示了一个具有多个方法的类,其中有些需要存储关于哪些用户访问该方法,以及被转移的资金数额的细节。
Employer | + updateEmployerFinancialBankAccount()
+ updateEmployerFinancialPaymentMethod()
+ updateEmployerFinancialRateGroup()
+ updateEmployerGeneralCount()
+ updateEmployerGeneralAddress()
+ updateEmployerGeneralStatus()
... |
图 2:一个雇主类
RUP 例子:
一个“活动”(以前的工作流程细节)由多个“任务”(以前的活动)组成,其中有些必须在任务完成时贡献一个过程“交付”(一包用于交付项目涉众的工作产品)。
连接点
“连接点”是程序源代码(过程描述)中一个明确定义的点,在那里关注横切了程序(交付过程)(并且扩展可能在此处发生)。对于一个有利的 AOP 方法来说,用于单独一个关注的多个连接点必须存在。
AOP 例子:
"当一个影响雇主财务的方法被调用"
RUP 等价物:
"在迭代的开端"
"当一个任务修改了迭代计划工件"
衡切点
一个“衡切点”是一个被用作程序声明和分组连接点的构造。衡切点允许您明确的引用程序代码(方法内容和过程)中的多个连接点。AOP 实现通常使用模板语言声明连接点。
AOP 例子:
pointcut employerFinancialUpdates(Employer e, User u): call (public void updateEmployerFinancial* ()); |
“employerFinancialUpdates”横切点是指那些被调用的以“updateEmployerFinancial”作为名称开头的方法。
RUP 等价物:
横切点 RUP_Element.BasicMethodElement.Task_set outputArtifactIsIterationPlan () : output_is (RUP_Element.BasicMethodElement.WorkProduct.rup_iteration_plan) |
这个横切点被称作“outputArtifactIsIterationPlan”,它描述了修改 IterationPlan 产品的任务(连接点)。
这些限定词名称将在本文后面关于 RUP 元模型的讨论时变得更加明确。
您可以采用一种更加宽松的方法来描述横切点,使用上下文无关的描述。例如,上面显示的横切点 能够被描述为:“找到所有修改 Iteration Plan 产品的任务”。这句提出了过程工程师识别那些必须关注和潜在扩展的任务的一个适当的需求。
方面
在 AOP 中,一个“方面”俱是一个封装特定关注行为的结构(通常为一个方法、模块或者类)。
AOP 例子:
public aspect logTransaction{pointcut employeeFinanceUpdates(Employer e, User u) : call(public void updateEmployerFinancials* ()) & args(e, u); after (Employer e) returning : employerFinanceUpdates(e, u) {< Advice >} } |
<Advice> 的实现提供如下。
RUP 等价物:
Extension Work Product (Artifact, Deliverable)
Extension Activity (Task, Activity, Iteration, Phase)
Extension Role
Extension Step
Extension Capability Pattern
Extension Delivery Process
RUP 例子:
"Rationalization phase" (extended phase)
" Program update memo" (extended artifact)
建议
“建议”就是一个解决关注的额外行为的物理实现。
AOP 例子:
System.out.println("\t>User : " +u.getFullUserName() + " has m ade a financial transaction through "); System.out.println("\t>method " + thisJoinPoint.getSignature());|-------10--------20--------30--------40--------50--------60--------70--------80--------9||-------- XML error: The previous line is longer than the max of 90 characters ---------| |
这个实现代码打印出访问方法的用户的名称和方法名称。
RUP 例子:
该任务的目的是: - 识别完成事件的一个用例流程的类;
- 将用例行为分发到那些类中,通过分析用例实现;
- 识别类的责任、属性和关联;
- 标注体系结构机制的用法。
为了更加完整的回顾 AOP 方法,请您参考本文最后“引用”一节中所提供的资源。
上一篇:什么是RUP 下一篇:【供学习交流】用RMC实现SE(Systems Engineering)实例 |