(计算机应用技术专业论文)pe系统的自动化重构研究与实践.pdf_第1页
(计算机应用技术专业论文)pe系统的自动化重构研究与实践.pdf_第2页
(计算机应用技术专业论文)pe系统的自动化重构研究与实践.pdf_第3页
(计算机应用技术专业论文)pe系统的自动化重构研究与实践.pdf_第4页
(计算机应用技术专业论文)pe系统的自动化重构研究与实践.pdf_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

浙江大学硕士学位论文摘要 摘要 企业级系统在满足人们不断增加的需求的过程中,变得日益庞大,而系统维 护工作和进一步开发变得越来越艰难。重构为解决这一问题提供了指导意见。 自动化是重构活动的一个趋势。为了提高重构效率、改善重构效果,出现了 不少自动化重构工具,不过目前的自动化重构工具大多关注于如何重构,而对何 处重构这一先决条件关注不足。 大规模系统中最常见的重构目标莫过于重复代码,本文对如何检测重复代码 做了大量的研究,对现有技术和工具进行了对比分析,从中选取了适用于大规模 软件系统的检测算法,实现并予以改进,开发了自己的工具。 本文详细阐述一个金融系统利用自动化重构工具进行重构的过程,包括重构 过程中遇到的种种问题,以及分析和解决方案。在重构实践中,还运用了大量设 计模式。 重构中诸多步骤采用自动化技术,使重构活动快捷而可靠,这是本文的特色 之一。本文提及的p e 系统是j 2 e e 平台上开发的金融软件系统,其中运用的自动 化重构之方法,可以拓展到其他系统,为类似系统的重构实践提供有价值的参考。 关键词:自动化重构,大规模系统,重复代码,设计模式 浙江大学硕士学位论文abstrt a b s t r a c t e n t e r p r i s ea p p l i c a t i o ns y s t e m sh a v et os a t i s f yp e o p l e si n c r e a s i n gd e m a n df o rn e w f e a t u r e s i nt h i sp r o c e s s ,t h e ya r eb e c o m i n gl a r g e ra n dl a r g e r , a n di ti sm o r ea n dm o r e d i f f i c u l tt om a i n t a i nt h es y s t e mo rt oh a v es o m ef u r t h e rd e v e l o p m e n tt oe n h a n c ei t r e f a c t o r i n gh a sp r o v i d e dg u i d a n c ea n ds u g g e s t i o n sf o rt h i sp r o b l e m a u t o m a t i o ni sat r e n do f r e f a c t o r i n ga c t i v i t i e s f o rt h er e q u i r e m e n t so fs p e n d i n g l e s st i m et oa c h i e v eb e t t e rr e s u l t s ,m a n ya u t o m a t e dr e f a c t o r i n gt o o l sh a v ec o m et o b e i n g h o w e v e r , t h ec u r r e n tr e f a c t o r i n gt o o l sa r em o s t l yc o n c e r n e dw i t hh o wt o r e f a c t o r i n g ,b u tn o tw h e r et or e f a c t o r i n g ,w h i c hi st h ek e yp r e r e q u i s i t ef o rr e f a c t o r i n g a c t i v i t i e s d u p l i c a t e dc o d ei nl a r g e 二s c a l es y s t e mi st h em o s tc o m m o nr e f a c t o r i n go b j e c t i v e s t h e r e f o r e ,t h i sp a p e rh a sd o n eal o to fr e s e a r c ho nh o wt od e t e c td u p l i c a t e dc o d et o g u i d er e f a c t o r i n ga c t i v i t i e s i tc o m p a r e sa n da n a l y s e se x i s t i n gt e c h n o l o g i e sa n dt o o l s , f r o mw h i c hi tc h o o s e ss o m ea l g o r i t h m ss u i tf o rl a r g e s c a l es y s t e m ,a n dt h e ni m p r o v e s t h e ma n d d e v e l o p si t so w n u s e f u lt o o l s t h i sp a p e re l a b o r a t e st h ew h o l ep r o c e s so fr e f a c t o r i n gaf i n a n c i a ls y s t e mw i t h a u t o m a t e dt o o l s ,i n c l u d i n gs o m eo ft h ep r o b l e m sa sw e l la st h ea n a l y s i sa n ds o l u t i o ni n t h i sp r o c e s s w ea l s ou s e dal o to f d e s i g np a t t e r n si nt h i sp r a c t i c e m a n ys t e p s o fr e f a c t o r i n gu s e sa u t o m a t e d t e c h n o l o g y ,w h i c hm a k e st h e r e f a c t o r i n ga c t i v i t i e sm o r ec o n v e n i e n ta n dr e l i a b l e t h i si so n eo ft h ec h a r a c t e r i s t i c so f t h i sp a p e r p es y s t e mm e n t i o n e di nt h i sp a p e ri saf i n a n c i a ls y s t e md e v e l o p e do nt h e j 2 e ep l a t f o r m t h em e t h o d so fa u t o m a t e dr e f a c t o r i n gu s e di nt h i sp a p e ra l s oc a nb e e x t e n d e dt oo t h e rs y s t e m s i tp r o v i d e sv a l u a b l er e f e r e n c ef o rr e f a c t o r i n gp r a c t i c eo f o t h e rs i m i l a rs y s t e m s a u t o m a t e dr e f a c t o r i n g ,l a r g e s c a l es y s t e m ,d u p l i c a t e dc o d e ,d e s i g n 浙江大学硕士学位论文图目录 图目录 图1 1p e 系统三层架构2 图1 3p e 系统业务逻辑层框架4 图3 1 后缀树算法应用实例2 0 图3 2b r o w s e 各模块中类之间代码相似度分布。2 2 图4 1p e 系统p u b l i s hl p a 模块的u i 3 2 图4 2p u b l i s h 各模块a c t i o nf o r w a r d 流程图3 6 图4 3 使用t e m p l a t e 模式重构p u b l i s ha c t i o n 3 8 图4 4 使用e c l i p s e 重构工具p u l lu p 子类方法到超类4 3 图4 5 使用f a c t o r y 模式重构p u b l i s hd a o 4 4 i i i 浙江大学硕士学位论文 图目录 表目录 表3 1 重复代码自动检测技术比较一1 6 表3 2e c l i p s e 重构工具汇总2 6 表4 1p e p u b l i s he j b 接口说明3 9 表4 2p e 访问权限控制示例4 8 i v 浙江大学研究生学位论文独创性声明 本人声明所呈交的学位论文是本人在导师指导下进行的研究工作及取得的 研究成臬。除了文中特别加以标注和致谢的地方外,论文中不包含其他人已经发 表或撰写过的研究成果,也不包含为获得逝姿态堂或其他教育机构的学位或 证书而使用过的材料。与我一同工作的同志对本研究所做的任何贡献均已在论文 中作了明确的说明并表示谢意。 繇弼一期:伽矿年纱j 日 学位论文版权使用授权书 本学位论文作者完全了解逝姿盘堂有权保留并向国家有关部门或机构 送交本论文的复印件和磁盘,允许论文被查阅和借阅。本人授权逝望盘堂可 以将学位论文的全部或部分内容编入有关数据库进行检索和传播,可以采用影 印、缩印或扫描等复制手段保存、汇编学位论文。 ( 保密的学位论文在解密后适用本授权书) 签名势砑 聊躲 签字日期q ,矿吻年加厂日 一, v 一飙劢歹夕日 浙江大学硕士学位论文第1 章绪论 第1 章绪论 本章主要介绍课题背景,使读者对p e 系统的整体架构以及各层次的主要技 术和功能有所了解。接下来阐述p e 系统中普遍存在的重复代码,如何检测这部 分重复代码,并利用自动化工具实施重构,正是本文的研究目标所在。本章最后 介绍了论文的组织结构,以供读者参考。 1 1 课题背景 本课题来源于浙江大学和某国际金融服务公司合作的p e 项目。p e 系统是该 公司的一个投资信息分析系统,它主要是向机构投资者提供投资信息。p e 系统是 个具有极高商业价值的系统,是支撑其公司表现和分析服务的重要金融产品。p e 项目主要为它的用户提供不同级别的,个性化的p f i v a t ee q u i t y 和r e a le s t a t e 市场 分析服务。其核心业务是根据预定义的规则,为用户提供发布、审核以及浏览报 表的服务。这些报表的来源可以是p e 自己的数据库、文件系统、或者由其他项 目组提供的外部接口提供。 p e 系统由1 9 9 5 年开发完成并投入运行,此后,系统有过很多次发布,添加 新的功能,提升系统性能。2 0 0 5 年开始,由于技术的发展和用户的需求增加,p e 系统面临重大变革,由原来的c s 架构,重组和演变为现在的b s 架构,以适应信 息时代的市场需求。至2 0 0 6 年初,p e 系统的第一个w e b 功能模块,b r o w s e c h a r a c t e r i s t i c s 正式上线,标志着p e 系统的w e b 化跨出了历史性第一步。 目前的p e 系统w e b 应用采用j 2 e e 解决方案实现。j 2 e e 架构是当前主流 的架构之一,目前大多数企业采用j 2 e e 技术的结构设计与解决方案。j 2 e e 体系 结构提供中间层集成框架用来满足无需太多费用而又需要高可用性、高可靠性以 及可扩展性的应用的需求。通过提供统一的开发平台,j 2 e e 降低了开发多层应用 的费用和复杂性,同时提供对现有应用程序集成强有力支持,完全支持e n t e r p r i s e j a v a b e a n s ,有良好的向导支持打包和部署应用,添加目录支持,增强了安全机制, 提高了性能。 浙江大学硕士学位论文第l 章绪论 p e 系统采取中美两端联合协作的方式开发和维护。笔者有幸从系统的w e b 化开始就加入这个项目,两年来一直致力于p e 系统的开发与维护。 1 2p e 系统架构简介 p e 系统采用经典的j 2 e e 分层架构模型。整个系统划分为三个层次:表现层、 业务逻辑层和持久层。系统架构如图1 1 所示。 s t r q t s 盯c 框架业务层数据层 居竺l犁 刀一 i r 4 -1i- - h n - - 静_ h - - ,- 一 _ l _ - ii 两霸 1j r “嘲 掣i l ;f 。 : il l 鬯! 日 l 肾 f 墨炀 。# 至兰写 :。目 - 蜀蔷鬲磊哥 趴:_ 一 昌一l 图1 1p e 系统三层架构 采用分层架构设计的优势在于: 分层模型一个最大的优点就是,降低系统耦合度,可以适应需求的不断 易变化,降低局部代码修改带来的风险。 表现层、业务逻辑处理与持久层数据访问脱藕,便于分包与分布式部署。 各个层次之间以接口调用为通信途径,使接口标准化成为可能。 系统的安全访问控制、事务处理以及并发控制等高层次需求,可以在分 层模式下得到最大程度的满足。 分层模型,有利于多人开发和异地开发的进行,提高开发效率。 2 浙江大学硕士学位论文第1 章绪论 1 2 1 表现层概述 p e 系统的表现层采用相当成熟的m v c 框架s t r u t s 。s t r u t s 是一个高度可配置、 高度扩展性的m v c 框架,几乎可以用它开发任何能想到的用j a v a 技术的w e b 应用。m v c 模式的每一部分在s t m c t s 中都有相关对应部分【1 1 。 s t r u t s 框架可分为以下四个主要部分,其中三个就和m v c 模式紧密相关: 模型( m o d e l ) ,本质上来说在s t r u t s 中m o d e l 是一个a c t i o n 类,开发者通 过其实现商业逻辑,同时用户请求通过控制器( c o n t r o l l e r ) 向a c t i o n 的转发过程是 基于由s t r u t s c o n f i g x m l 文件描述的配置信息的。 视图( v i e w ) ,v i e w 是由与控制器s e r v l e t 配合工作的一整套j s p 定制标签 库构成,利用它们可以快速建立应用系统的界面。 控制器( c o n t r o l l e r ) ,本质上是一个s e r v l e t ,将用户端请求转发到相应的 a c t i o n 类。 一系列用来做x m l 文件解析的工具包,s t r u t s 是用x m l 来描述如何自动产 生一些j a v a b e a n 的属性的,此外s t r u t s 还利用x m l 来描述在国际化应用中的用 户提示信息的,这样一来就实现了应用系统的多语言支持。 1 2 2 业务逻辑层概述 p e 系统的业务逻辑层,采用的是j 2 e e 经典的e j b 技术。采用e y b 开发应用 系统有很多优点,如: 标准的j a v a 技术便利应用系统可以在许多不同的服务器平台上运行; 修改应用系统变得容易,对单个组件进行增加、修改、删除等操作不会 对应用系统体系结构产生很大影响。 应用系统经过划分之后,使得组件之间相互独立,又可以相互协作,提 供给用户的是该用户所需要的组件,等等。 浙江大学硕士学位论文第1 章绪论 图1 2p e 系统业务逻辑层框架 p e 系统的业务逻辑层框架如图1 2 所示。按功能模块划分,每个模块对应一 个无状态会话b e a n 。各个模块通过e j b 组件,调用d a o 接口访问数据库,数据 库查询有返回结果的,在e j b 容器中封装成d a t a b e a n ,再以一定的格式提供给前 台a c t i o n ,为表现层提供标准化数据。 1 2 3 持久层概述 p e 系统持久层,采用的是美国团队开发的j d b c 访问框架:p e v c c o m m o n 。 p e v c c o m m o n 包支持自动识别本地环境从而选择数据来源。它通过j n d i 寻找 d a t a s o u r c e 来实现对数据库的访问。 p e v c c o m m o n 为业务逻辑层提供了两个数据封装和若干数据访问接口: d b r e q u e s t 和d b q u e r y 分别是为修改和查询操作封装s q l 的接口; d b r e q u e s t h a n d l e r 是各种数据库访问操作( 包括事务处理) 的实现者,为业务逻 辑层提供了若干访问接口。 1 3 研究目标和内容 在短短两年的时间里,p e 系统已经从最初的1 个模块迅速壮大到现在的1 3 个模块。当然在这个急速壮大的过程中,不少代码由于开发计划紧任务重而忽略 了其质量。不少代码完全是“拷贝粘贴修改”的产物,因此,系统冲充斥了大 量的重复代码。还有很多过大的类和过长的方法,这些给后继开发维护人员的工 作带来了极大的不便,代码风格的拙劣已经不止是影响阅读的问题,而且在修补 b u g 和功能改进的时候都让人难以下手。更严重的是,维护人员由于不了解代码 4 浙江大学硕士学位论文 第1 章绪论 的冗余性,只修改了部分而遗漏了其他,这样造成的后果已经严重到影响产品交 付的程度,对于此类冗余代码的整理可以说迫在眉睫。 重构作为改善代码结构的重要手段,成为首选。但是,从哪里着手开始重构, 如何去发现重复代码和那些过长的类和方法,是个相当实际的问题。由于系统的 庞大,不可能依靠人工方式去发现,求助于自动化工具是必然。然而,在实践中, 现有的用来检测和定位重复代码的工具为数不多,而且其功能也比较简单,并不 适合检测大规模系统中重复代码的检测与定位。这就迫使我们自己去开发一套工 具,来辅助p e 系统重构活动。 本文期望通过利用自主开发的工具,对p e 系统现有代码中的重复性冗余进 行检测,并借助其有效的报告结果,开始p e 系统的自动化重构。重构将会涉及 前台表现层、后台业务逻辑层以及前后台接口。在做每一步重构之前都充分考虑 到代码结构变化带来的风险,准备完整的测试套,并在重构之后及时测试。在重 构的过程中,充分利用现有的技术和工具,使重构活动进行的有序而且高效。实 践的目的是,改善p e 系统的代码结构,使之具有更好的可读性、可维护性、可 重用性以及可扩展性。p e 系统的重构,对于类似系统的重构活动具有重要的参考 价值。 1 4 论文组织 本文接下来的第2 、3 、4 章是文章的重点章节。 第2 章主要介绍软件重构理论,包括应在何时重构、何处重构,和重构活动 的一般步骤。 第3 章是自动化重构研究的核心章节。这一章首先介绍了自动化重构技术的 现状,自动化重构按照重构的步骤分为几个阶段,这章重点研究了重构的目标代 码检测和重构实施技术。其中,第2 节列举了目前的重复代码检测技术和工具, 并通过对比分析,选取了更适合大规模系统的文本匹配技术,并给出了算法的优 化和实现;第3 节则主要是介绍重构实施技术及其工具。 第4 章是自动化重构实践部分,主要针以p e 系统存在的大量重复代码为重 构目标,进行系统的重构,从表现层到业务逻辑层重构的重点环节将在这章中详 气 浙江大学硕士学位论文第1 苹绪论 细介绍。另外,重构实践中遇到的难点问题,也将在这章第3 节进行专题分析。 最后在第5 章,笔者对p e 系统的是自动化重构实践进行了总结,同时,提 出重复代码检测工具的不足之处,以及其功能可扩展之处。 1 5 本章小结 本章概述了p e 系统的全貌,从功能和架构上总结了p e 系统的模式。不论是 系统的分层模式选型,还是各个层次的技术定位,无疑都为系统的敏捷开发,和 高效运行带来了极大的便利。然而,经过长期的大规模的开发和修改,系统的在 貌似稳固的框架下,已经渐渐充斥了大量冗余代码,重复代码首当其冲,给系统 维护和进一步开发带来了诸多阻挠。p e 系统的重构是本文实践的主要内容,在这 个过程中,应用一些列自动化工具辅助重构,是本文的特色。 6 浙江大学硕士学位论文第2 章重构理论概述 第2 章重构理论概述 重构,通常被定义为“在不改变代码外在行为的前提下,对代码做出修改,以 改进程序的内部结构”。重构是一种有纪律的、经过训练的、有条不紊的程序整理 方法,可以将整理过程中不小心引入错误的机率降到最低。本质上说,重构就是 “在代码写好之后改进它的设计【2 1 。 重构可以有效地改进代码的可读性、可维护性、可重用性和可扩展性。在重 构过程中,开发人员亦可发现系统的b u g ,甚至是设计的瑕疵。重构可以让系统 在原有功能完好的前提下,优化其代码结构,为以后的维护和功能添加都带来诸 多便利。 重构可以是软件开发循环的一部分。在极限编程方法学中,开发总是或者增 加新的测试和功能,或者重构代码来改善内部的一致性和清晰性。测试保证了重 构没有改变代码的外部行为【3 1 。 重构也可以是代码维护中的一部分,既不修正错误,又不增加新的功能性。 而是用于提高代码的可读性或者改变代码的结构和设计,使其在将来更容易被维 护。特别是,在现有的程序的结构下,给一个程序增加一个新的行为会非常困难, 因此开发人员可能先重构这部分代码,使加入新的行为变得容易。 2 1 何时重构 重构理论提出了著名的“事不过三,三则重构”的经典论断,意思是,一旦同 样或者类似的代码出现三次甚至更多的时候,考虑重构【2 1 。这提供了很好的指导 意见。 如果不是将重构作为开发循环中的一个环节,从实际需求出发,应该在以下 情况下考虑重构: ( 1 ) 添加新功能时 最常见的重构时机就是希望给软件添加新特性时。一般这时候问题就出来 了,最初的设计很难让我们添加新代码时还能很好的重用既有代码,或者为了添 7 浙江大学硕士学位论文第2 章重构理论概述 加新特性,可能要拷贝原有功能块中很多代码,必然出现重复代码。为了改善原 有设计的灵活性,而不引入重复代码,重构是最好的选择。 ( 2 )修补漏洞时 修补漏洞时,经常遇到这样的问题,为了改一个b u g ,不得不整个工程甚至 更多代码范围的全搜索,才能找到类似的问题还有可能在哪出现,以求一并改之, 如若不然,这个b u g 将可能继续留在系统中,等待下次崩溃的时候被发现。如果 是这样,不如立刻考虑重构。 ( 3 ) 复审代码时 往往在复审代码时,复审人根据经验,对被审核代码提出诸多改进意见,在 代码风格、分包、设计模式运用、兼容旧有代码等方面提出扩展性要求,以保证 整个工程的代码质量,和适应以后可能的需求变化。 2 2 何处重构 相比何时重构,何处重构更加困扰开发人员。文献 2 】总结了2 2 种代码中的 “坏味道 ,为我们在何处重构指引了正确的方向:重复代码、过长的函数、 过大的类成为罪恶三甲,当然过长参数列,数据泥团,中间人等也颇为常见【2 】, 下面取其中一部分做重点剖析。 1 重复代码 重复代码是软件中最司空见惯、最刺鼻的坏味道。它可能很明显,也可能微 妙难寻。完全相同的代码中当然存在明显的重复,而微妙的重复会出现在表面不 同但是本质相同的结构或者处理步骤中。经常可以通过应用形成t e m p l a t em e t h o d 重构,去除类层次中不同子类里存在的明显和微妙的重复。如果不同子类中的方 法除了对象创建不同之外其他实现方式都类似,可以用f a c t o r ym e t h o d 引入多态 创建重构,为使用t e m p l a t em e t h o d 去除更多重复做好准备。如果类的构造方法 包含重复代码,通常可以通过应用链构函数重构去除这种重复。如果有单独的 代码处理一个对象或者一组对象,也许可以通过应用c o m p o s i t e 替换一多之分重 构去除重复。如果类层次的多个子类都实现了自己的c o m p o s i t e ,而且实现可能 完全相同,这事可以提取c o m p o s i t e 重构。如果对象处理方式的区别仅在于它们 8 塑垩奎堂堡主堂堡丝茎 釜! 兰重塑堡堡塑垄 的接口不同,应用通过a d a p t e r 统一接口重构就能为去除重复的处理逻辑做好准 备。如果有条件逻辑用于处理空对象,而且相同的空逻辑在整个系统中都是重 复的,那么可以引入n u l lo b j e c t ,消除重复并简化系统【4 1 。 2 过长的方法 早期的编程语言中,函数调用动作需要额外的开销,这使得人们不太乐意使 用“小函数”。现代的o o 语言几乎完全免除了进程内函数调用动作额外的开销, 所以现在写那样过长的函数,愈发使人难以理解。为增加函数的可读性、灵活性 与共享性,重构方法自然成为开发人员的首选。对于过长的函数,提取方法( e x t r a c t m e t h o d ) 是最常用的方式,这当然是绝大多数自动化重构工具所支持的。 3 过大的类 试图用一个超大的类完成很多功能的想法是不好的,因此,在代码设计之初, 这种想法就应被扼杀掉。p e 系统开发的准则上,这一点是明确提出的,不过尽管 如此,对于已有的代码,还是存在不少类过大的问题,由于历史原因它们没能遵 守准则。此类问题在既有大型系统中非常常见,建议用提取类( e x t r a c tc l a s s ) 和 提取子类( e x t r a c ts u b c l a s s ) 等方法对其重构,这些方法也是有自动化重构工具 支持的。 4 过长的参数列表( l o n gp a r a m t e rl i s t ) 太长的参数列难以理解,太多参数会造成前后不一致,不易使用,而且一旦 需要更多数据,就不得不修改它。如果将对象传递给函数,大多数据修改都没有 必要,因为很可能只需在函数内增加一两条请求,就能得到更多的数据。 5 发散式变化( d i v e r g e n tc h a n g e ) 如果某个类经常因为不同的原因在不同的方向上发生变化,d i v e r g e n tc h a n g e 就出现了。针对于- - # b 界变化的所有相应修改,都只应该发生在单一类中。 6 霰弹式修改( s h o t g u ns u r g e ? y ) 与d i v e r g e n tc h a n g e 类似,但恰恰相反。如果每遇到某种变化,都必须在许 多不同的类内做出许多小修改以回应之,所面临的就是s h o t g u ns u r g e r y 。如果需 要修改的代码散布四处,不但很难找到它们,也很容易忘记某个重要的修改。 9 浙江大学硕士学位论文第2 章重构理论概述 d i v e r g e n tc h a r g e 是指“一种变化引发对一个类的相应修改 。这两种情况下都 倾向于整理代码,取得“外界变化 与“待改类 呈现一对一关系的理想境地。 7 依恋情节( f e a t u r ee n v y ) 有一种经典气味是:函数对某个c l a s s 的兴趣高过对自己所处之h o s tc l a s s 的 兴趣。这种孺慕之情最通常的焦点便是数据。最根本的原则是:将总是一起变化 的东西放在一块儿。“数据”和“引用这些数据 的行为总是一起变化的,但也 有例外。如果例外出现,就搬移那些行为,保持“变化只在一地发生 。 8 数据泥团( d a t ac l u m p s ) 常常可以在很多地方看到相同的三或四笔数据项:两个类内的相同值域 ( f i e l d ) 、许多方法签名式( s i g n a t u r e ) 中的相同参数。这些总是绑在一起出现的 数据应该抽象封装到更少甚至一个数据类中。 9 s w i t c h 代码段( s w i t c hs t a t e m e n t s ) 面向对象程序的一个最明显的特征就是:少用s w i t c h ( 或c a s e ) 语句。从本 质上说,s w i t c h 语句的问题在于重复。你经常会发现同样的s w i t c h 语句散布于不 同的地点。如果要为它添加一个新的c a s e 子句,必须找到所有s w i t c h 语句并修改 它们。面向对象中的多态( p o l y m o r p h i s m ) 概念可为此带来优雅的解决办法。 1 0 冗余类( l a z yc l a s s ) 创建的每一个类都得有人去理解它,维护它,这些工作都是要花钱的。如果 一个类的所得不值其身价,它就应该消失。 1 1 令人迷惑的暂时值域( t e m p o r a r yf i e l d ) 有时会看到这样的对象:其内某个实例变量仅为某种特定情势而设。这样的 代码让人不易理解,因为通常认为对象所有时候都需要它的所有变量。在变量未 被使用的情况下猜测当初其设置的目的,会让人费解。 1 2 中间人( m i d d l em a n ) 对象的基本特征之一就是封装( e n c a p s u l a t i o n ) 对外部时间隐藏其内部 细节。封装往往伴随委托。但是人们可能过度运用委托。也许某个c l a s s 接口有一 半的函数都委托给其他类,这样就过度运用了。 l o 堑垩奎堂堡主堂竺丝茎 茎三兰重塑墨堡塑垄 13 狎呢关系( i n a p p r o p r i a t ei n t i m a c y ) 继承往往容易造成关系过度亲密,对于这些过于亲密的类,应该考虑拆散彼 此的调用联系,或者通过e x t r a c tc l a s s 将两个类之间的共同点移植到一个新的类 中。 1 4 数据类( d a t ac l a s s ) 它们拥有一些值域( f i e l d s ) ,以及用于访问( 读写) 这些值域的函数,除此 之外一无长物。对于这样的“不会说话的数据容器 ,应该尽可能的添加一些 对纯数据类的调用行为函数。 1 5 被拒绝的遗赠( r e f u s e db e q u e s t ) 子类应该继承超类的数据和函数。但如果它们不想或不需要继承,需要为这 个子类新建一个兄弟类,再运用p u s hd o w nm e t h o d 和p u s hd o w nf i e l e d 把所有 用不到的函数下推给那个用兄弟。 1 6 过多的注释( c o m m e n t s ) 如果注释太多已经变的多余了,这说明局部代码逻辑亟待整理。应该意识到, 应该通过重构减少或者消除这些注释。 2 3 重构的一般步骤 诚如重构的定义所指出的,重构活动,对代码结构进行改变的过程,必须确 保对其可察觉功能不产生影响( 严格意义上说,重构可能会带来某种程度上的性 能的提升,而性能是可察觉的,这里不做严格分辨以简化说辞) 。因此,任何重 构活动必须遵循这个原则,有序进行。 下面我们来明确重构活动的一般步骤【5 】: ( 1 )找出系统中哪些部分需要重构,即定位重构目标代码; ( 2 )决定对目标代码实施哪种重构方法; ( 3 )确保实施的方法能够维持系统的可察觉行为不变; ( 4 )实施重构,重构每一步都要有测试跟进; ( 5 )提出重构活动对软件质量或者过程的影响; ( 6 )维护系统相关文档的一致性,包括需求、设计以及测试文档的更新。 1 1 塑垩奎堂堡主堂垡笙奎 蔓! 兰霎塑里丝矍堕 需要说明的是,每一次重构,都要执行一系列的步骤,这些步骤要保证代码 和原代码相一致。因此在重构时,测试是十分重要的。应为重构改变了代码的结 构,你要保证重构后代码的功能没有被改变。手工重构时,一套好的测试方案是 必须的。使用自动重构工具是,测试也是必要的,但不需要很频繁,应为自动重 构工具不会产生手工重构时的那些错误,如拼写错误。在e c l i p s e 中可以使用j u n i t 方便的为程序创建测试代码,具体方法不在本文描述【6 l 。 2 4 本章小结 本章通过重构理论的概述,让我们认识到对于大型金融系统,重构是维持其 代码可读性、可维护性、可重用性以及可扩展性的一个适用的选择。重构理论包 含了何时重构与何处重构的论述,以及重构的一般步骤。这其中,对于何处重构, 真正的行之有效的方法并不多见,笔者一直致力于这方面研究,力求以自动化检 测工具完成对重构目标代码的检测与定位,具体研究和成果在下一章中阐述。 1 2 浙江大学硕士学位论文第3 章自动化重构技术研究 第3 章自动化重构技术研究 自动化重构就是利用现有的集成开发环境和一些有效的重构工具辅助开发 人员进行代码重构,最大程度节约人力成本,保证代码质量的前提下提高重构效 率。所谓自动化重构,往往无法实现“全自动”,通常意义上是指利用工具辅助重 构。 本章将对自动化重构的研究现状进行简单介绍。之后重点研究重读代码的自 动化检测技术,通过对比现有的技术,选择适合大规模系统的检测算法。实现并 改进算法,开发自己的工具,并利用其对p e 系统进行分析。最后,还将介绍e c l i p s e 提供的主要重构工具,为下一步实施重构做准备。 3 1 自动化重构研究的现状 目前众多i d e 往往包括重构浏览器支持一种半自动的重构方式。它可以帮助 开发人员发现其中哪部分可以被重构,并选择最适当的重构应用,实际重构工作 是自动化完成的。与手动重构相比,半自动化方法可大幅度地提高生产率,可能 是1 0 倍或更岁5 1 。从开发人员的角度看,重构工具另一个主要优点是,它们使 重构行为保持了原有的特性,大大减少了调试和测试的开销,众所周知,这两项 活动都是非常耗费时间和体力的。应用自动化重构还一个好处是,它可以很容易 u n d o ,让软件以恢复其原始状态。 一些研究证明了全自动重构的可行性,提出编译器的优化技术,可被视为全 自动化的重构技术的例子之一。这些优化转变,对用户是完全透明的,他们的目 标是改善其性能,但保持其行为。但就重构活动动机而言,编译器优化的结果是 产生机器理解的语言而非易于人理解的语言,因此,这种重构并不具备软件工程 上的意义。当面对大型软件时,没有人的参与,重构的方向和结果都是难以预料 的。 塑鋈奎堂堡主兰垡丝苎釜! 兰鱼塑些重塑茎查里茎 正因如此,半自动重构虽然需要更多的人机交互,但仍然是最有效的方法。 因为相当一部分重构所需的知识,仍酝酿在开发者的头脑里。本文中,除本节上 面部分之外,提及“自动化重构”之处均指交互的“半自动化重构”。 目前的自动化重构工具,绝大多少关注于如何重构,也有些工具致力于定位 重构目标代码的,但多数是基于编译技术的。它们往往解析单片代码,一个类或 者一个文件,根据语言语法特性,发现代码中诸如局部变量声明而未使用,或者 仅使用一次可被声明为f i n a l 等问题。其局限在于,只能针对类或文件代码片内的 代码优化提供参考,而未能发现组件包乃至系统级别的重构目标。 对于大规模系统,譬如p e 这样的拥有十几个模块、千余文件、十几万行代 码的系统,重复代码、过长的方法、过大的类等是最常见的重构目标。而其中重 复代码是p e 系统最突出的问题,应首先列入重构计划,是我们重构的重点目标。 在长期的软件开发实践中,笔者发现,要彻底清查大规模系统中的重复代码绝非 易事,因此开始思考在检测与定位系统级别的重复代码上做些研究。 3 2 重复代码检测算法研究 3 2 1 重复代码检测的现有研究 目前,对重复代码检测的算法研究已有许多,综合大多数研究成果来看,检 测重复代码的途径大致可以归为两类:一类是基于某种语言的检测技术,针对特 定语法,利用抽象语法树的对比,发现代码中的相同或者相似代码段,并可通过 比较其相似度来衡量原代码的冗余程度;另一类是语言无关的检测技术,一般基 于文本匹配技术,通过找出两个类文件或者文本片段之间的相同文本行,发现冗 余代码段【_ 7 1 。本文将对以上两种方式做多方面的对比,之后提出自己的算法改进 方案和实现。 3 211 基于抽象语法树的检测 这种检测方法,一般要先通过特定语言的解释器将代码解析成抽象语法树 ( a b s t r a c ts y n t a xt r e e ) ,代码中每一个t o k e n 对应树上的一个节点。然后试图通 1 4 浙江大学硕士学位论文第3 章自动化重构技术研究 过比较抽象语法树的任意两个子树,寻找相同或者相似的a s t 子树,这个过程的 算法时间复杂度是d 向乡。相似度的计算是递归算法,每个节点的相似度由其子树 上各分支节点的相似度加权平均得到,除非它已经是叶子节点,算法时间复杂度 是d 例。最终的报告,将给出a s t 中重复子树对应于原代码的重复代码段,以及 代码相似度的值【8 】。 3 2 1 2 基于文本匹配的检测 相比上面的抽象语法树检测,基于文本匹配的检测,更加直观。它一般不区 别语言特性,直接比较两个代码段文本行。它一般以代码行为单位进行比较【9 1 。 两段代码可以看作是两个代码行序列,找出两个序列的相同子序列,即找到重复 代码。由相同代码行的数目经过计算,可以得到两段代码的相似度。采用动态匹 配算法的时间复杂度是p 伽乡,而后缀树算法的时间复杂度更胜一筹,是d 例, 详细算法会在后面两节讨论。 3 2 1 3 现有检测技术对比 c c f i n d e r 先使用词法分析器对源代码进行预处理,包括将标识符换成统一的 特殊符号,去掉包前缀,去掉访问控制关键字等,再切分成t o k e n 流。把所有的 t o k e n 构造成一棵后缀树,使用后缀树算法( 下文有详细描述) ,可以用d 俐时间 复杂度( n 为t o k e n 的个数) 找到所有相同的t o k e n 序列。基于t o k e n 进行原子匹 配的算法的特点是较高匹配率和相对较低的准确率。 从源代码的文本结构及词法的角度去检测重复代码,不需要使用重量级的语 法分析器,较容易扩展到对多种程序语言乃至纯文本文档的检测。基于文本的匹 配算法也较基于树或者图的算法有更好的时空效率,能够支持对大规模的软件系 统的检测。文献 1 0 1 的实验结果显示,如使用一台普通的p c 对j - d k l 3 0 ( 约5 7 万行,1 8 7 7 个文件) 进行检测时,耗时仅3 分钟。 文献 8 等通过使用静态分析器把源代码构造成抽象语法树,然后在语法树上 寻找相同或相似子树来检测克隆代码。文献【8 】使用以下的公式来计算两棵子树的 相似度:s i m i l a r i t y = 2 s ( 2 s + l + r ) ,其中s 是两棵树共有的结点数,l 是树1 中的不 同结点数,r 是树2 中的不同结点数。基于语法树的检测的最大缺点是需要针对 1 5 浙江大学硕士学位论文 第3 章自动化重构技术研究 每一种目标语句构造能够识别其所有语法结构的静态分析器,代价昂贵,基于树 的匹配需要非常大的时空开销,如文献【8 】的实验结果显示,他们的算法检测1 0 万行源代码,需要6 0 0 m 内存和1 2 0 分钟的c p u 时间。 表3 1 重复代码自动检测技术比较 类别比较单元 匹配算法优点缺点 基于抽 抽象语法树匹配考虑了程序的语法结构,建立语法树的代价高。基于 象语法树节点对拷贝后修改有更佳的检树的匹配算法复杂,时空效 树测效果;报告结果较准确。 率低,难以应刚于人规模软 件。 基于文 文本行,后缀树,语言无关,无需使用语法忽略了语法、语义信息,难 本匹配 t o k e n 动态匹配解释器;时空效率佳,易以检测剑进行了某些修改动 用于企业级的人规模系统 作的拷贝行为;报告的无效 结果较多。 通过以上分析和表3 1 的对比可以得出,抽象语法树算法时间和空间复杂度 较高,而且代码解析过程需要第三方工具辅助,在实践中这是个非常昂贵的代价。 而基于文本匹配的检测技术,实际中更易于操作,从时空代价上考虑,它更适合 针对大规模系统的海量代码进行重复代码的检测。因此,我们选择后者,并尝试 对现有算法进行改进,开发自己的工具辅助检测重构目标代码。 3 2 2 动态匹配算法介绍与改进 上一节提到了基于文本匹配的动态匹配算法。参考文献【9 ,1 1 】中叫做动态模 式匹配算法( d y n a m i cp a t t e r nm a t c h ) ,实际上,其基本思想源于动态规划( d y n a m i c p r o g r a m m i n g ) 1 2 】。下面介绍下动态匹配算法。 3 2 2 1 动态匹配算法介绍 方法d m - l e n g t h 以两个序列作为输入,x = 和y = ,其中x i ( i 1 。m ) 与乃( j 1 n ) 分别是两个序列的单元向量。它将维 护两张表c o 。m ,0 n 】和b 1 。m ,1 n 】,这两张表初始化时候都是逻辑空值,在比较 两个序列的公共序列向量的时候,被逐行依次从左到右填充。这里,c o 。m ,0 n 】 用来记录两个序列的匹配数,为i n t 值,c 【i ,j 】的值为子序列x i = 与 1 6 浙江大学硕士学位论文第3 章自动化重构技术研究 子序列y j = 的最大匹配数。而b 1 一m ,1 n 】用来标记两子序列的最 优匹配。具体算法如下: d m - l e n g t h ( x ,y ) m 一l e n g t h ( x ) m 一l e n g t h ( y ) f o ri 卜lt om d oc 【i ,o 】- 0 f o r j 卜0t on d oc 0 ,j 】一0 f o ri4 - - 1t om d of o r j 卜1t on d of f x i = y j t h e nc i ,j 】卜c 【i - l ,j - 1 】+ 1 b i ,j

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论