您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > 3901110721-李奇-软件配置管理实验报告3
1《软件配置管理》实验报告项目名称代码味道及重构专业班级软件1107班学号3901110721姓名李奇实验成绩:批阅教师:年月日2正文要求实验二代码味道及重构实验实验学时:4每组人数:1实验类型:2(1:基础性2:综合性3:设计性4:研究性)实验要求:1(1:必修2:选修3:其它)实验类别:3(1:基础2:专业基础3:专业4:其它)一、实验目的1.熟悉常用的代码味道的涵义和特征;2.熟悉常用的代码重构手段;3.学会使用常用重构手段对常见代码味道进行重构;4.掌握一种代码味道识别工具(CSDT);5.熟悉Eclipse重构菜单;6.学会使用EclipseAST来解析Java源代码;7.设计并实现两种代码味道的自动识别方法;8.设计并实现一种代码味道的自动重构方法。二、实验内容1.根据常见代码味道的特点,选取合适的重构手段对它们进行重构,填写相应的表格;2.掌握一款代码味道识别工具,并使用该工具对至少一个实验项目进行代码味道识别,寻找存在代码味道的类和代码片段;【参考资料:七款代码味道识别工具】3.学习使用Eclipse重构(Refactor)菜单,从实验项目中选取合适的代码进行重构操作;4.自学EclipseAST,包括获取、访问、创建和修改AST等操作;【EclipseAST学习资料:://blog.csdn.net/lovelion/article/details/19050155://blog.csdn.net/lovelion/article/details/20700467】5.选取两种代码味道,设计并实现相应的代码味道识别方法,选取至少一个实验项目进行测试;6.结合EclipseAST,选取一种代码味道,设计并实现一种代码味道的自动重构方法,至少提供两个重构测试用例,并对重构前后的代码进行分析。补充:实验素材及相关资料(1)EclipseAST所需jar包下载地址:(2)ASTView下载地址:(3)5个实验项目下载地址:(4)10个补充实验项目下载地址:三、实验要求1.针对常用的代码味道,选择合适的重构手段,填写相应的表格,要求表格需填写完整;2.选取一款代码味道识别工具,记录对实验项目的代码味道识别结果,包括识别到的类名和代码片段;3.使用Eclipse重构(Refactor)菜单对实验项目中的代码进行重构(自行选取合适的代码),要求提供重构前后的代码【至少需使用10种重构手段】;4.针对两种代码味道,设计并实现相应的识别方法,要求对方法原理进行说明,需提供文字介绍(可包含流程图)、核心代码以及相应的测试结果和分析;5.针对一种代码味道,设计并实现相应的重构方法,要求对重构流程进行说明,需提供文字介绍(可包含流程图)、核心代码以及相应的测试结果和分析。四、实验步骤1.填写代码味道和重构手段表格;2.选取一种代码味道识别工具,对常见代码味道进行识别,记录识别结果;3.学习使用EclipseRefactor菜单,熟悉至少10种常用的重构操作;4.学习EclipseAST,熟悉使用AST来解析Java源代码;5.设计并实现两种代码味道识别方法,对已有项目进行测试,记录与分析实验结果;6.设计并实现一种代码味道重构方法,对测试用例进行实验,记录与分析实验结果。五、实验结果1.针对常用的代码味道,选择合适的重构手段,填写如下表格:代码味道名称常用重构手段过长方法(LongMethod)抽取函数(ExtractMethod)以查询取代临时变量(ReplaceTempWithQuery)引入参数对象(IntroduceParameterObject)分解条件表达式(DecomposeConditional)过大类(LargeClass)太多实例变量或太多代码:ExtractClass(提炼类)、ExtractSubclass(提炼子类)把数据和行为移到一个独立的领域对象,但需要保留一些重复数据:DuplicateObservedData(复制“被监视数据”)确定客户端如何使用:ExtractInterface(提炼接口)基本类型偏执(PrimitiveObsession)将原本单独存在的数据值替换成对象:ReplaceDataValuewithObject(以对象取代数据值)如果想要替换的数据值是类型码,而它并不影响行为:ReplaceTypeCodewithClass(以类取代类型码)如果有与类型码相关的条件表达式:ReplaceTypeCodewithSubclass(以子类取代类型码)、ReplaceTypeCodewithState/Strategy(以State/Strategy取代类型码)如果有一组应该总是被放在一起的字段:ExtractClass(提炼函数)如果在参数列中看到基本类型的数据:IntroduceParameterObject4(引入参数对象)发现自己正从数组中挑选数据:ReplaceArraywithObject(以对象取代数组)纯稚的数据类(DataClass)对于public字段:EncapsulateField(封装字段)如果一个类内含容器类的字段,如果没有得到恰当的封装:EncapsulateCollection(封装集合)对于那些不该被其他类修改的字段:RemoveSettingMethod(移除设值函数)找出Getter/Setter函数被其他类运用的地点:MoveMethod(搬移函数)如果无法搬移整个函数:ExtractMethod(提炼函数)将Getter/Setter函数隐藏起来:HideMethod(隐藏函数)重复代码(DuplicatedCode)同一个类的一个/两个方法含有相同的代码:ExtractMethod(提炼函数)两个互为兄弟的子类含有相同的代码:ExtractMethod(提炼函数)、PullUpMethod(函数上移)、FormTemplateMethod(塑造模板函数)两个毫不相关的类含有相同的代码:ExtractClass(提炼类)异曲同工的类(AlternativeClasseswithDifferentInterfaces)两个函数做同一件事,却有着不同的签名:RenameMethod(函数改名)将某些行为移入类,直到两者的协议一致为止:MoveMethod(搬移函数)必须重复而冗赘地移入代码:ExtractSuperclass(提炼超类)Switch惊悚现身(SwitchStatement)与类型码相关的函数或类:ExtractMethod(提炼函数)、MoveMethod(搬移函数)、ReplaceConditionalwithPolymorphism(以多态取代条件表达式)、ReplaceTypeCodewithSubclass(以子类取代类型码)、ReplaceTypeCodewithState/Strategy(以State/Strategy取代类型码)只在单一函数中有一些选择事件,且不想改动它们:ReplaceParameterwithExplicitMethods(以明确函数取代参数)选择条件之一是null:IntroduceNullObject(引入Null对象)令人迷惑的暂时字段(TemporaryField)一个对象中某个实例变量仅为某种特定情况而定:ExtractClass(提炼类)在“变量不合法”的情况下创建一个Null对象,从而避免写出条件式代码:IntroduceNullObject(引入Null对象)5被拒绝的遗赠(RefusedBequest)子类不想或不需要继承超类(先为子类新建一个兄弟类):ExtractSubclass(提炼子类)、PushDownMethod(函数下移)、PushDownField(字段下移)子类复用了超类的行为(实现),却又不愿意支持超类的接口,拒绝继承超类的实现:ReplaceInheritancewithDelegation(以委托取代继承)数据泥团(DataClumps)两个类中有相同的字段、许多函数签名中的参数相同:ExtractClass(提炼类)缩短参数列表、简化函数调用:IntroduceParameterObject(引入参数对象)、PreserveWholeObject(保持对象完整)狎昵关系(InappropriateIntimacy)类之间的关系过于亲密:MoveMethod(搬移函数)、MoveField(搬移字段)、ChangeBidirectionalAssociationtoUnidirectional(将双向关联改为单向关联)如果两个类存在共同点:ExtractClass(提炼类)、HideDelegate(隐藏“委托关系”)从继承体系中分离子类:ReplaceInheritancewithDelegation(以委托取代继承)冗赘类(LazyClass)对于几乎没用的组件:InlineClass(将类内联化)如果某些子类没有做足够的工作:CollapseHierarchy(折叠继承体系)依恋情结(FeatureEnvy)函数对某个类的兴趣高过对自己所处类的兴趣:MoveMethod(搬移函数)、MoveField(搬移字段)函数中只有一部分对其他类更感兴趣:ExtractMethod(提炼函数)、MoveMethod(搬移函数)判断哪个类拥有最多被此函数使用的数据,然后就把这个函数和那些数据放在一起过度耦合的消息链(MessageChains)a.getB().getC().getD().getE()……存在一长串getThis()或一长串临时变量:HideDelegate(隐藏“委托关系”)中间人(MiddleMan)过度运用委托(一半及以上的函数都委托给其他类):RemoveMiddleMan(移除中间人)如果“不干实事”的函数只有少数几个:InlineMethod(内联函数)如果中间人还有其他行为,需要对原对象的行为进行扩展:ReplaceDelegationwithInheritance(以继承取代委托)6发散式变化(DivergentChange)如果某个类经常因为不同的原因在不同的方向上发生变化【找出某特定原因而造成的所有变化】:ExtractClass(提炼类)霰弹式修改(ShotgunSurgery)把所有需要修改的代码放进同一个类中:MoveMethod(搬移函数)、MoveField(搬移字段)如果眼下没有合适的类可以安置这些代码,就创造一个把一系列相关行为放进同一个类中:InlineClass(将类内联化)平行继承体系(ParallelInheritanceHierarchies)让一个继承体系的实例引用另一个继承体系的实例:MoveMethod(搬移函数)、MoveField(搬移字段)不完美的库类(IncompleteLibraryClass)如果只想修改库类的一两个函数:IntroduceForeignMethod(引入外加函数)如果想要添加一大堆额外行为:IntroduceLocalExtension(引入本地扩展)过长参列()向已有对象发出一条请求就可以取代一个参数:ReplaceParameterwithMethod(以函数取代参数)参数缺乏合理的对象归属:IntroduceParameterObject(引入参数对象)将来自同一个对
本文标题:3901110721-李奇-软件配置管理实验报告3
链接地址:https://www.777doc.com/doc-5888881 .html