基于AOP策略模式的实现机制*
2016-04-13江华丽
江华丽
(福建师范大学 闽南科技学院,福建 泉州 362332)
基于AOP策略模式的实现机制*
江华丽
(福建师范大学 闽南科技学院,福建 泉州 362332)
在当前软件需求越来越复杂的时代,策略模式作为23种经典的设计模式之一,它有着其重要的发挥舞台。本文首先将传统基于OOP策略模式的局限性进行分析说明,提出基本的策略模式以及“链式”策略模式基于AOP的具体实现,解决传统策略模式可能出现的代码分散、代码混乱问题;接着进行复杂度方面的实验对比分析;最后分析基于AOP的策略模式可能的应用场景。
策略模式;AOP;设计模式
0 引言
模式(Pattern)一词最初出现在建筑学领域上,素有“模式之父”之称的美国加利福尼亚大学Christopher Alexander博士给出其经典的定义:每个模式都描述环境中不断出现的问题,提出该问题的解决方案的核心。通过这种方式,可以无数次地使用那些已有的解决方案,无须再重复相同的工作[1-3]。设计模式(Design Pattern),即是一种方法论,是前人经过无数次实践,加以分类、整理,并从中提取出的在特定场景下解决一般设计问题的方法总结。可以说它是一种解决一类特定问题的模板或者现在所说的最佳实践。设计模式的提出与应用,使得在软件开发过程中,编写的代码更加容易被人理解,代码更加可靠。OOP(面向对象编程)与设计模式的目的皆是为了使代码获得更强大的可复用性等,这使得两者进行无缝的连接。当前设计模式几乎都是基于OOP上实现的,而策略模式是设计模式的[1]其中一种。策略模式在OOP上的实现技术虽然已经可以解决策略模式在开发过程中出现的大部分问题和需求,但是随着软件开发需求越来越多,业务逻辑越来越复杂,在解决一些复杂的需求时,策略模式这种基于OOP的实现越来越显示出它的局限性。OOP这种面向对象编程的思想,虽然解决了软件开发中划分角色的问题,实现软件的模块化设计,但其定义的是一种从上到下的关系,当在解决从左到右的关系时却显得很无力。如在实现系统中各个模块都存在的公共功能,例如日志、安全性、性能监测、异常捕获等时,如果仍用OOP技术,就可能导致代码混乱、分散等问题,从而导致代码可读性差,代码质量低,可复用性、可扩展性差。AOP就是一种有效可行的解决方案,它是一种“横切”的技术,通过把上述公共功能封装成一个独立的模块即称之为“切面”[4-6],然后把它织入到各个模块中。本文就当前较为流行、使用较为广泛的设计模式之一——策略模式,探讨其在AOP下的实现。
1 策略模式
1.1 策略模式结构
当前,设计模式种类最为经典的有23种,可以归纳分为三大类,即创建型模式、行为型模式和结构型模式。策略模式为行为型模式之一,它定义一系列算法,并且将这一系列的算法封装成为策略类,使这些策略类相互独立又可以相互替换,向外则提供公共的接口即策略接口。策略类的调用完全取决于调用者,这使得当需求或者说策略算法发生改变时,只需新增策略类,而无需修改其他代码,从而不会影响到用户,使得策略类独立于用户而变化。总的来说,策略模式是对算法的包装,是把使用算法的责任和算法本身分离开来,委派给不同的对象管理[7]。策略模式定义以下三种角色,其结构图如图1所示。
图1 策略模式结构图
策略模式提倡“针对接口编程”的模式,而使用接口的目的是为了统一标准或者说是指定一种强制的规定[3]。使用策略模式是由用户/开发者发起并根据其具体的需求、具体的操作决定调用哪种具体的策略类。当前,策略模式的使用十分广泛,例如:JDK中的Comparable、Comparator接口,Swing中的布局管理器LayoutManager,边界类Border等。
1.2 AOP
AOP(Aspect Oriented Programming)即面向切面编程,是近些年来开始流行的一种新的编程范式。AOP为开发者提供一种描述横切关注点的机制,并能够自动将横切关注点织入到面向对象的软件系统中,从而实现了横切关注点的模块化[8]。AOP的结构图如图2所示。
图2 AOP结构图
AOP可以说是OOP的一种改进或者补充。OOP能够很好地实现软件开发中类从上到下的纵向关系,解决模块功能的角色划分问题,使得很多的关注点都模块化。然而,OOP在处理横向问题即横切关注点时将会出现代码交织/混乱、代码分散等问题。其实质在于OOP倾向处理的是“一维空间”的问题,而横切关注点则是将其变成二维空间上的问题,这使得OOP在实现二维问题时使用很糟糕的映射。当前,实现AOP技术有很多,如AspectJ,Aspect Werkz,AspectC++,Jboss AOP,Spring AOP,AOP/ST,DynInst,Nanning等。从编织的方式可以分为静态编织和动态编织;从编织的时刻可以分为编译时编织、载入时编织和运行时编织三大类别。而实现AOP技术的实质即动态代理。现在比较流行的实现动态代理的模式主要有:JDK动态代理和CGLIB动态代理。本文将使用Spring AOP框架实现AOP技术[9]。
2 策略模式在AOP具体实现
AOP(面向切面编程)比较擅长处理那些分散在各个模块中又有别于核心业务关注点的公共功能需求,例如日志、安全性、性能监测、异常捕获等。下面将以各个模块中的日志处理为例进行讨论。在软件开发特别是WEB开发中,经常采用MVC模式,而DAO层一般用来作为数据访问层。操作数据无非就是增删改查操作,在增删改查数据时应对其进行日志生成,操作数据日志又可细分为增、删、改、查4种日志,即4种日志策略,部分实现代码如下:
//日志策略接口
public interface LogStrategy {
public void log();
}
//保存数据日志策略实现类
public class LogStrategyImpSave implements LogStrategy{
private Logger logger = Logger.getLogger(this.getClass());
@Override
//其他策略实现类只需分别实现log方法,其他地方相同
public void log() {
logger.info("保存数据...");
// 定义处理保存数据日志的切面类
public class UserSaveDaoAspect {
private LogStrategy logStrategy; //getter、setter方法省略
//环绕通知
@Around(value="pointCutMehtod()")
publicvoid around(ProceedingJoinPoint pjp){try {Object object= pjp.proceed();
2.1 分析
当需求发生变化如增删改查日志的格式改变了,这时只需新增实现日志策略接口LogStrategy,并根据需求实现里面的方法,然后在配置文件中注册类的bean信息并修改注入到logStrategy属性的信息,而不需要修改其他类的代码,这也符合软件开发的“修改封闭,扩展开放”的原则。
2.2 与传统基于OOP的策略模式对比
上述举例为J2EE软件开发中DAO层的日志处理,而事实上在其他分层中如service层、action层等很多地方都需要日志处理。对于传统的基于OOP的策略模式则需要在每一处都调用日志策略具体实现类的方法,这种重复的工作使得代码看起来臃肿、不易于维护,即代码混乱、代码分散;而对于基于AOP的策略模式则只需定义好切面类和切入点,并在切面类中的环绕通知里调用公共功能,这里即为日志处理的方法,并配置好配置文件信息即可,而不需要在每处进行日志处理。
对于较为复杂的策略模式,如在处理复杂业务需求时,往往不仅使用一个策略实现类,而且需要使用多组策略类别下的策略实现类才能实现需求。可以结合设计模式中另外一种模式即责任链模式,把策略模式改装为“链式”策略模式。
3 对比分析
通常用软件的复杂度来评价一个软件/算法的好坏,即“简单就是可靠的”。本文将使用下面4个指标来对比和评价传统的基于OOP的策略模式与基于AOP的策略模式。
(1)圈复杂度(CC):用于衡量模块中的判定结构的复杂程度。圈复杂度越大其质量一般越低,越难以维护。业界标准一般小于等于15。
(2)扇出复杂度(FOC):用于衡量模块间的层次调用(调用下级模块)情况。扇出复杂度高,则表示模块的复杂度高,需要控制和协调过多的下级模块。业界标准一般小于等于20。
(3)无注解编码语句(NCSS):在文件、类和方法中一般分别小于等于2 000、1 500、50。
(4)N条路径复杂度(NPath):表示一个方法中各种可能的执行路径总和。业界标准一般小于等于200。
本节将测试上述第2节中实现的例子即J2EE软件开发中的日志处理,其各个复杂度指标的实验数据如表1所示。
表1 各个复杂度指标实验数据
从表1可以看出,基于AOP的策略模式相对于传统的基于OOP的策略模式在各个复杂度指标上都大大降低。因为基于AOP的策略模式把分散在各个模块中的公共功能的业务逻辑封装成一个切面类,然后再织入到各个模块中,而不是如传统的基于OOP的策略模式那样直接在各个模块中重复编写那些公共功能的实现,大大降低了代码的复杂度。这也表明基于AOP的策略模式很好地解决了传统的基于OOP的策略模式出现的代码分散、代码混乱的问题,是软件开发中对于在各个模块中都有的公共功能问题的很好的解决方案。
4 应用场景
策略模式将一系列的策略算法封装成相互独立又可相互替换的“针对接口编程”的模式,而AOP是一种擅长于处理横向关系,将各个模块中有别于核心业务关注点的公共功能局部化、模块化的新的编程范式,两者皆是为了提高软件的可扩展性、可复用性。基于AOP的策略模式不仅在处理软件中横向关系需求时显得游刃有余,并且使得软件开发中开发人员各司其职。某一领域的专家不可能同时对加密、性能、同步、访问控制、分布等都熟悉精通,而只需知道对应的功能接口的调用就可以。基于AOP的策略模式可以应用在以下方面:
(1)系统中模块间的公共功能,且未来可能发生需求变化。如日志、安全性、性能监测、异常捕获、认证、加密等。
(2)模块间的插件。各个插件即是各种算法功能的策略实现类,也可在其中添加“钩子”函数,使插件具备可插拔。
(3)模块间的个性化定制。个性化的定制是未来对用户最具魅力的功能,也是未来个性化软件的方向。事先将各种个性化选择封装在策略实现类中,其基于AOP的实现使得个性化的选择效果应用在各个模块中。
5 结论
基于OOP的策略模式虽然已经可以很好地实现策略模式,将一系列策略算法封装成相互独立、相互可替换的策略实现类,大大提高软件的可重用性和可扩展性,但是由于OOP本身存在的局限性即在解决软件需求中横向关系时可能出现代码混乱、代码分散等问题,使得基于OOP的策略模式在处理这类问题时代码可读性差、效率低、代码质量差、代码重用率低以及难以维护难以扩展等。本文利用AOP处理横切关注点的优势,提出基于AOP的策略模式,很好地解决了传统基于OOP的策略模式的问题。
[1] 张海翔,秦翼. 从Java类库看设计模式[J]. 电子世界, 2013(22):13-14.
[2] 张舒晋. 嵌入式软件实用设计模式[J]. 自动化应用, 2015(1):36-38.
[3] 刘新强,韩阳峰. 基于AOP技术的邮件日志系统研究[J]. 电子设计工程,2014,22(18):45-48.
[4] 幸德波. 基于AOP的J2EE应用程序性能监控系统研究与实现[D]. 杭州:浙江大学,2014.
[5] 赵文杰. 基于AOP的异常处理研究与应用[J]. 计算机光盘软件与应用,2014(24):66-68.
[6] 蒋廷耀,王训宇,关国翔,等. 一种策略模式的AOP实现及应用[J]. 计算机应用与软件,2010,27(1):121-123.
[7] 薛冰. 改进AOP技术在软件开发中的应用与研究[D]. 大连:大连交通大学,2013.
[8] 陈发堂,牛勇清,韩娜娜,等.协议一致性测试平台的搭建及仿真实现[J].电子技术应用,2014,40(4):137-140.
[9] 宋建华,税光泽.无线传感器网络的数据安全与隐私保护[J].微型机与应用,2013,32(3):4-6.
The strategy pattern based on AOP implementation
Jiang Huali1
(Minnan Institute of Science and Technology,Fujian Normal University,Quanzhou 362332, China)
Strategy pattern is one of 23 kinds of classic design patterns. The strategy pattern has its important position in the stage. This paper firstly introduces the limitation of the traditional strategy mode based on OOP analysis, then puts forward the basic strategy of model and the ‘chain’ strategy based on concrete implementation of the AOP, which solves the traditional strategy pattern’s problems, such as code scattered and code disorder. Finally ,through the experiment analysis, it analyzes the prospective strategy pattern application.
strategy pattern;AOP;design mode
福建省教育厅项目(JB11266)
TN311
A
1674-7720(2016)01-0009-03
江华丽.基于AOP策略模式的实现机制[J].微型机与应用,2016,35(1):9-11.
2015-09-07)
江华丽(1985-),女,研究生,讲师,主要研究方向:电子和通信等。