摘要 设计规范只表示纯粹的想法但项目的成功来说实现这些规范是必须的传统的实现方式是代码评审Hammurapi是一个遵循设计的工具提供了自动而且一致的方式来实现设计规范因此使代码评审更加有效而轻松在这篇文章中作者介绍了Hammurapi的使用并与其他类似工具进行比较最后还给出演示如何使用的例子 作为一个JEE架构师我需要分发详细设计给项目团队通过UML模型我也会分发那些捕获最佳实践的设计规范例如在Struts应用中我推荐避免在Action类中使用实例变量因为Action类是单例的而且多个线程同时访问一个Action类实例是很平常的其他例子如在任何DAO应用中一个重要的设计方针是关闭所有打开的数据库资源如果没有这么做通常将导致灾难尤其是在一个产品环境中 想法是很好的但是实现才是关键现在最常用的实现设计规范的方法是做代码评审通常是有经验的成员检查代码来找出不符合规范的地方这些代码可能是没有遵守编码规范或者设计规范 这是一种非常低效的方法主要表现在两方面这需要两种资源(开发人员和评审人员)质量变成评审人员的职责此外在我的经历中由于评审人员过于重视规范使得他们与开发人员对立起来而这对一个团队来说是不好的 许多年前我接触过Checkstyle这是一个自动强制代码规范的工具他与Ant无缝集成并且由基于XML配置文件来驱动 Hammurapi是一个与Checkstyle类似的工具只是他用来强制设计规范Hammurapi是一个由Pavel Vlasov开发的开源软件他可以基于一套设计规范来分析代码库当他遇到违反规范的地方会在报告中标识就像Checkstyle一样他与Ant无缝集成并且由基于XML配置文件来驱动 运行Hammurapi 你可以直接从命令行运行Hammurapi或者作为Eclipse的插件来使用在这篇幅文章中我主要讨论如何通过Ant任务来运行Hammurapi 注意你可以从资源中下载与本文对应的源程序 与Ant集成非常容易如下面代码所示 <target name=design_review depends=init> <taskdef name=hammurapi classname=orghammurapiHammurapiTask> <classpath> <fileset dir=${hammurapihome}\lib> <include name=**\*jar></include> </fileset> </classpath> </taskdef> <hammurapi> <src dir=src/> <output dir=docs\review/> <classpath> <pathelement location=${$logjhome}\lib\logjjar\/> <pathelement location=${weblogichome}\lib\weblogicjar\/> </classpath> </hammurapi> </target> 第一行定义了一个design_review的目标他依赖于init目标—初始化构建的属性(如第四行的${hammurapihome})第二行定义了一个hammurapi新任务这个Ant任务由orghammurapHammurapiTask类实现内嵌的classpath元素定义了定义这个任务所需要的类库 第九行声明了一个先前定义的hammurapi任务运行这个任务相当简单只要定义内嵌的src元素就可以了他会告诉任务上哪儿查找源程序然后定义另一个元素output这告诉任务在哪儿输出报告第十行告诉任务在项目任务目录下的src目录下查找需要评审的源程序第十一行告诉任务输出报告到项目目录下的docs\review中 第十二行的classpath元素是可选的他定义了源程序依赖的类库位置 Hammurapi带有多个内建的检查器每一个对应一个设计规范 先前列出的Ant代码片断将在logj源程序上运行Hammurapi代码将被解压到项目目录下的src目录图显示了生成的报告的打开页面Hammurapi最令人激动的特性就是他生成的全面的报告 educitycn/img_///jpg >图例示了报告l的主页右边的框架显示了三个标题结果严重性小结和文件 结果段落显示整体评审的统计如图中所示个包中的个文件被评审了其中包含违反规范的地方 严重性小结段落以表的方式来显示违反规范的地方每一项属于一个严重级别预定义的级别包含级级别是最严重的 文件段落(图)列出了每一个被评审的文件和他所违反的规范 educitycn/img_///gif >虽然严重性小结段落可以回答如多少空catch块被找到文件段落可以回答在Appenderjava中多少规范被违反但是Hammurapi最有用的功能是他可以在报告中显示违反规范所在的代码行数如让我们分析一下设计规范ER空catch块(图)点击数字列的超链就可以显示报告这个违反的文件如图所示 educitycn/img_///gif>在很多文件中报告显示LogRecordjava ()在第行违反了这个规范在行数下的超链直接链接到源程序如图的示 educitycn/img_///gif >虽然从整个代码库的运行Hammurapi是最常用的方式但你也可以使用增量的评审自上一次评审后改变的代码这在代码库非常大评审需要很长时间时非常有用 另一个运行Hammurapi的有效方式是可以处理压缩文件和其所依赖的并生成压缩的结果文件这种方式在开发团队分布在不同的地理位置时非常有用在这个情况下源程序被压缩并传送到远程的评审点 其他设计评审工具 Hammurapi并非是仅有的代码评审工具Metrics也是一个可以作为Eclipse的很流行的类似工具然而他有两个主要的缺点首先他和Eclipse紧密结合想要与Ant结合相当麻烦由于需要Eclipse的类库这使得不使用Eclipse作为IDE的项目不能使用Metrics其次你不能用Metrics构造自定义的检查器(Hammurapi可以)这限制了用户只能使用内建的检查器 其他的工具还有PMD类似于Hammurapi他与Ant无缝集成而且允许自定义检查器然而PMD生成的报告不如Hammurapi生成的报告全面 Hammurapi如何工作 Hammurapi这样的代码分析工具都带有语言分析器语言分析器是一种输入语言代码并输出抽象语法树的工具这个树上的节点代表语言标识例如考虑一下简单的算术表达式+ 语言分析器会解析他成为一个如图所示的语法树在这个树中节点+代表操作符标识节点和是操作数标识 educitycn/img_///jpg>Hammurapi使用ANTLR(另一个语言识别工具)作为语言分析器然而ANTLR API是相当底层的为改善可用性Hammurapi使用另一个API基于ANTLR 的JSEL(Java源程序工程类库)来访问抽象语法树 一旦树构建完成一种树遍历算法就被用来访问树中每一个节点每次访问到一个节点一种回调机制(Visitor模式)被用来提示相应的检查器在这些回调方法中检查器收集相关的信息来确定是否有违反规范的地方存在 构建自定义的检查器 一个自定义检查器可以更好理解Hammurapi框架如前面所提一种Struts的最佳实践是避免Action类中的实例变量所以我们会构建一个自定义检查器ActionClassInspector他扫描源程序中的Action类如果一个Action类被发现他就扫描是否存在实例变量如果一个以上的实例变量被发现他就标识出相应的违反 图例示了ActionClassInspector类的变量和方法所有的检查器都继承自orghammurapiInspectorBase类 educitycn/img_///jpg >图例示了Hammurapi框架激活ActionClassInspector类的回调方法的时序图框架解析源程序并构建一个抽象语法树然后访问树中的每一个节点当一个类节点被访问时他调用visit( v:VariableDefinition )方法因为通常一个类可能包含多个变量这个方法可能会被调用多次 educitycn/img_///jpg>下面的代码显示了visit( c:Class )方法 public void visit( compavelvlasovjselClass c ) throws Exception { isActionClass = cisKindOf( orgapachestrutsactionAction); return; } 这个方法负责确定是否一个特定的类是Action类这个测试在第三行被执行如果测试是肯定的那么isActionClass被设置为真这个规范仅应用于Action类 下面的代码例示了visit( v:VariableDefinition )方法 public void visit( compavelvlasovjselVariableDefinition v ) throws Exception { List modifiers; Scope scope; if( thisisActionClass ) { modifiers = vgetModifiers( ); scope = vgetEnclosingScope( ); if( scope instanceof compavelvlasovjselimplClassImpl ) { if( ntains( static ) ) { ;//Do nothing; this class is compliant } else { contextreportViolation( (SourceMarker)d Violation ); |