中南软件配置管理实验二_第1页
中南软件配置管理实验二_第2页
中南软件配置管理实验二_第3页
中南软件配置管理实验二_第4页
中南软件配置管理实验二_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

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

文档简介

1、软件配置管理实验报告项目名称 代码味道及重构试验 专业班级 学 号 姓 名 实验成绩:批阅教师:2016年 04月 20日实验二 代码味道及重构实验实验学时: 4 每组人数: 1 实验类型: 2 (1:基础性 2:综合性 3:设计性 4:研究性)实验要求: 1 (1:必修 2:选修 3:其它)实验类别: 3 (1:基础 2:专业基础 3:专业 4:其它)一、实验目的1. 熟悉常见代码味道的涵义和特征;2. 熟悉常用的代码重构手段;3. 学会使用常用重构手段对常见代码味道进行重构;4. 学会使用常用设计模式来对代码进行重构;5. 掌握一种代码味道识别工具(CSDT);6. 熟悉Eclipse重构

2、菜单;7. 学会使用Eclipse AST来解析Java源代码;8. 设计并实现一种代码味道的自动识别方法;9*. 设计并实现一种代码味道的自动重构方法。二、实验内容1. 根据常见代码味道的特点,选取合适的重构手段对它们进行重构,填写相应的表格;2. 选取三种设计模式,分析这些设计模式可以消除的代码味道以及在重构到设计模式的过程中所使用的重构手段,填写相应的表格;3. 掌握一款代码味道识别工具,并使用该工具对至少一个实验项目进行代码味道识别,寻找存在代码味道的类和代码片段;【参考资料:七款代码味道识别工具4. 学习使用Eclipse重构(Refactor)菜单,从实验项目中选取合适的代码进行重

3、构操作;5. 自学Eclipse AST,包括获取、访问、创建和修改AST等操作,使用Eclipse AST设计并实现一个类信息统计小程序;【Eclipse AST学习资料: 】6. 选取一种代码味道,设计并实现相应的代码味道识别方法,选取至少一个实验项目进行测试;7*(选做). 结合Eclipse AST,选取一种代码味道,设计并实现一种代码味道的自动重构方法,至少提供两个重构测试用例,并对重构前后的代码进行分析。补充:实验素材及相关资料(1) Eclipse AST所需jar包下载地址:(2) ASTView下载地址:(3) 5个实验项目下载地址:(4) 10个补充实验项目下载地址:三、实

4、验要求1. 针对常见的代码味道,选择合适的重构手段,填写相应的表格,要求表格需填写完整;2. 选取三种常用的设计模式,分析这些设计模式可以消除的代码味道以及在重构到设计模式的过程中所使用的重构手段,填写相应的表格,要求表格需填写完整;3. 选取一款代码味道识别工具,记录对实验项目的代码味道识别结果,包括识别到的类名和代码片段;4. 使用Eclipse重构(Refactor)菜单对实验项目中的代码进行重构(自行选取合适的代码),要求提供重构前后的代码【至少需使用10种重构手段】;5. 学习Eclipse AST,要求通过Eclipse AST设计一个类信息统计小程序,可以统计一个类中方法的个数、

5、属性的个数、源代码行数、代码行最多的方法名以及代码行数、参数个数最多的方法名及其参数的个数等信息;6. 针对一种代码味道,设计并实现相应的识别方法,要求对方法原理进行说明,需提供文字介绍(可包含流程图)、核心代码以及相应的测试结果和分析;7*(选做). 针对一种代码味道,设计并实现相应的重构方法,要求对重构流程进行说明,需提供文字介绍(可包含流程图)、核心代码以及相应的测试结果和分析。四、实验步骤1. 填写代码味道和重构手段表格;2. 填写设计模式、代码味道和重构手段表格;3. 选取一种代码味道识别工具,对常见代码味道进行识别,记录识别结果;4. 学习使用Eclipse Refactor菜单,

6、熟悉至少10种常用的重构操作;5. 学习Eclipse AST,使用AST设计并实现一个类信息统计小程序;6. 设计并实现一种代码味道识别方法,对已有项目进行测试,记录与分析实验结果;7*(选做). 设计并实现一种代码味道重构方法,对测试用例进行实验,记录与分析实验结果。五、实验结果1. 针对22种常见的代码味道,选择合适的重构手段,填写如下表格:代码味道名称常用重构手段过长方法(Long Method)抽取函数(Extract Method)以查询取代临时变量(Replace Temp With Query)引入参数对象(Introduce Parameter Object)保持对象完整(P

7、reserve Whole Object)以函数对象取代函数(Replace Method with Method Object)分解条件表达式(Decompose Conditional)过大类(Large Class)提炼类(Extract Class)提炼子类(Extract Subclass)提炼接口(Extract Interface)复制“被监视数据”(Duplicate Observed Data)过长参数列(Long Parameter List)以函数取代参数(Replace Parameter with Method)引入参数对象(Introduce Parameter O

8、bject)保持对象完整(Preserve Whole Object)过多的注释(Comments)提炼函数(Extract Method)函数改名(Rename Method)引入断言(Introduce Assertion)夸夸其谈的未来性(Speculative Generality)折叠继承体系(Collapse Hierarchy)将类内联化(Inline Class)移除参数(Remove Parameter)函数改名(Rename Method)内联函数(Inline Method)移除函数(Remove Method)重复代码(Duplicated Code)提炼函数(Extr

9、act Method)函数上移(Pull Up Method)塑造模板函数(Form Template Method)提炼类(Extract Class)异曲同工的类(Alternative Classes with Different Interfaces)函数改名(Rename Method)搬移函数(Move Method)提炼超类(Extract Superclass)Switch惊悚现身(Switch Statement)提炼函数(Extract Method)、搬移函数(Move Method)、以多态取代条件表达式(Replace Conditional with Polymor

10、phism)、以子类取代类型码(Replace Type Code with Subclass)、以State/Strategy取代类型码(Replace Type Code with State/Strategy)以明确函数取代参数(Replace Parameter with Explicit Methods)引入Null对象(Introduce Null Object)基本类型偏执(Primitive Obsession)以对象取代数据值(Replace Data Value with Object)以类取代类型码(Replace Type Code with Class)以子类取代类型

11、码( Replace Type Code with Subclass)、以State/Strategy取代类型码 (Replace Type Code with State/Strategy)提炼函数(Extract Class)引入参数对象(Introduce Parameter Object)以对象取代数组(Replace Array with Object) 纯稚的数据类(Data Class) 封装字段(Encapsulate Field)封装集合(Encapsulate Collection)移除设值函数(Remove Setting Method)搬移函数(Move Method)

12、提炼函数(Extract Method)隐藏函数(Hide Method)数据泥团(Data Clumps)提炼类(Extract Class)引入参数对象(Introduce Parameter Object)、保持对象完整(Preserve Whole Object)令人迷惑的暂时字段(Temporary Field)提炼类(Extract Class)引入Null对象(Introduce Null Object)被拒绝的遗赠(Refused Bequest)提炼子类(Extract Subclass)、函数下移(Push Down Method)、字段下移(Push Down Field

13、)以委托取代继承(Replace Inheritance with Delegation)狎昵关系(Inappropriate Intimacy)搬移函数(Move Method)、搬移字段(Move Field)、将双向关联改为单向关联(Change Bidirectional Association to Unidirectional)提炼类(Extract Class)、隐藏“委托关系”(Hide Delegate )以委托取代继承(Replace Inheritance with Delegation)冗赘类(Lazy Class)将类内联化(Inline Class)折叠继承体系(C

14、ollapse Hierarchy)依恋情结(Feature Envy)搬移函数(Move Method)、搬移字段(Move Field)提炼函数(Extract Method)、搬移函数(Move Method)判断哪个类拥有最多被此函数使用的数据,然后就把这个函数和那些数据放在一起 过度耦合的消息链(Message Chains)隐藏“委托关系”(Hide Delegate)中间人(Middle Man)移除中间人(Remove Middle Man)内联函数(Inline Method)以继承取代委托(Replace Delegation with Inheritance)发散式变化(

15、Divergent Change)提炼类(Extract Class)霰弹式修改(Shotgun Surgery)搬移函数(Move Method)、搬移字段(Move Field)将类内联化(Inline Class)平行继承体系(Parallel Inheritance Hierarchies)不完美的库类(Incomplete Library Class)搬移函数(Move Method)、搬移字段(Move Field)引入外加函数(Introduce Foreign Method)引入本地扩展(Introduce Local Extension)2. 选取三种常用的设计模式,分析这些

16、设计模式可以消除的代码味道以及在重构到设计模式的过程中所使用的重构手段,填写如下表格:设计模式可消除代码味道重构手段模板方法模式重复代码抽取函数(Extract Method) 桥接模式发散式变化提炼类(Extract Class)策略模式Switch惊悚现身提炼函数(Extract Method)、搬移函数(Move Method)、以多态取代条件表达式(Replace Conditional with Polymorphism)、以子类取代类型码(Replace Type Code with Subclass)、以State/Strategy取代类型码(Replace Type Code

17、with State/Strategy)以明确函数取代参数(Replace Parameter with Explicit Methods)引入Null对象(Introduce Null Object)3. 选取一款代码味道识别工具和实验项目进行代码味道识别实验,记录如下信息:(1) 代码味道检测工具名称:checkStyle(2) 实验项目名称【至少1个】:(3) 实验结果:代码味道名称代码味道数量代码味道实例【类名或者代码片段,如果存在该代码味道的话至少需提供1个实例】过长参数列表10java.awt.Graphics public Boolean drawImage (Image ima

18、ge, int x1Dest, int y1Dest, int x2Dest, int y2Dest, int x1Source, int y1Source, int x2Source, int y2Source, Color color, ImageObserver obs)过大类5javax.swing.JTable过多的注释3/ 启动聊天页面信息刷新线程Thread thread = new Thread(this);thread.start();/ Icon log=new ImageIcon("imageschat.jpg");/ lblBack = new JL

19、abel(log);/ lblBack.setBounds(1, 1, 600,420);/ pnlChat.add(lblBack);/*scrnsize = toolkit.getScreenSize();frmChat.setLocation(scrnsize.width / 2 - frmChat.getWidth() / 2,scrnsize.height / 2 - frmChat.getHeight() / 2);*/Image img = toolkit.getImage("appico.jpg");frmChat.setIconImage(img);4.

20、使用Eclipse Refactor菜单,掌握一些常用的重构操作,并在实验项目中选取合适的代码实施重构,填写如下表格:重构名称重构之前代码重构之后代码Renameimport java.util.Scanner;public class shuzifanzhuan public static void main(String args)Scanner input = new Scanner(System.in);int a = input.nextInt();int b = input.nextInt();int resultA=0;int resultB=0;while(a>10)re

21、sultA = resultA*10+a%10;a=a/10;resultA = resultA*10+a%10;while(b>10)resultB = resultB*10+b%10;b=b/10;resultB = resultB*10+b%10;System.out.println(resultA+resultB);import java.util.Scanner;public class digitalFlip public static void main(String args)Scanner input = new Scanner(System.in);int a = i

22、nput.nextInt();int b = input.nextInt();int resultA=0;int resultB=0;while(a>10)resultA = resultA*10+a%10;a=a/10;resultA = resultA*10+a%10;while(b>10)resultB = resultB*10+b%10;b=b/10;resultB = resultB*10+b%10;System.out.println(resultA+resultB);Movepackage movingfeature.movemethod;/* * * author

23、lenovo * move field: * 1. for field _interestRate, Encapsulate Field * 2. copy "private double _interestRate;" and " get/set _interestRate" into class AccountType * 3. rewrite get/set _interestRate to delegate to class AccountType * 4. for get/set _interestRate, Inline * 5. remov

24、e field _interestRate * * move method: * 1. for method interestForAmount_days(), Move method * 2. for method overdraftCharge(), for field _daysOverdrawn, Extract local Variable * 3. for field _daysOverdrawn in method overdraftCharge(), Introduce Parameters * 4. delete "final int daysOverdrawn =

25、 daysOverdrawn;" then Move method */public class Account double overdraftCharge() if (_type.isPremium() double result = 10;if (_daysOverdrawn > 7)result += (_daysOverdrawn - 7) * 0.85;return result; elsereturn _daysOverdrawn * 1.75;double bankCharge() double result = 4.5;if (_daysOverdrawn &

26、gt; 0)result += overdraftCharge();return result;double interestForAmount_days(double amount, int days) return _interestRate * amount * days / 365;private double _interestRate;private AccountType _type;private int _daysOverdrawn;class AccountType public boolean isPremium() return false;package moving

27、feature.movemethod;/* * * author lenovo * move field: * 1. for field _interestRate, Encapsulate Field * 2. copy "private double _interestRate;" and " get/set _interestRate" into class AccountType * 3. rewrite get/set _interestRate to delegate to class AccountType * 4. for get/set

28、 _interestRate, Inline * 5. remove field _interestRate * * move method: * 1. for method interestForAmount_days(), Move method * 2. for method overdraftCharge(), for field _daysOverdrawn, Extract local Variable * 3. for field _daysOverdrawn in method overdraftCharge(), Introduce Parameters * 4. delet

29、e "final int daysOverdrawn = daysOverdrawn;" then Move method */public class Account double bankCharge() double result = 4.5;if (_daysOverdrawn > 0)result += _type.overdraftCharge(_daysOverdrawn);return result;private AccountType _type;private int _daysOverdrawn;package movingfeature.mo

30、vemethod;class AccountType public boolean isPremium() return false;public double get_interestRate() return _interestRate;double interestForAmount_days(double amount, int days) return get_interestRate() * amount * days / 365;double overdraftCharge(int daysOverdrawn) if (isPremium() double result = 10

31、;if (daysOverdrawn > 7)result += (daysOverdrawn - 7) * 0.85;return result; elsereturn daysOverdrawn * 1.75;private double _interestRate;Extract super classpackage generation.extractsuperclass;import java.util.Enumeration;import java.util.Vector;public class Department public Department(String nam

32、e) _name = name;public int getTotalAnnualCost() Enumeration e = getStaff();int result = 0;while (e.hasMoreElements() Employee each = (Employee) e.nextElement();result += each.getAnnualCost();return result;public int getHeadCount() return _staff.size();public Enumeration getStaff() return _staff.elem

33、ents();public void addStaff(Employee arg) _staff.addElement(arg);public String getName() return _name;private String _name;private Vector _staff = new Vector();package generation.extractsuperclass;public class Employee public Employee(String name, String id, int annualCost) _name = name;_id = id;_an

34、nualCost = annualCost;public int getAnnualCost() return _annualCost;public String getId() return _id;public String getName() return _name;private String _name;private int _annualCost;private String _id;package generation.extractsuperclass;import java.util.Enumeration;import java.util.Vector;/* * * a

35、uthor yaoyufei * 1. compare with Employee, getName, getCost could be extracted to superclass * 2. Extract Superclass _name, getName * here, eclipse has a bug. You may need to add "extends Party" manually. * adjust constructor * 3. Rename getTotalAnnualCost to getAnnualCost * Pull up getAnn

36、ualCost * 4. More better, refactor to composite design pattern. (I won't do it here) */public class Department extends Partypublic Department(String name) super(name);Overridepublic int getAnnualCost() Enumeration e = getStaff();int result = 0;while (e.hasMoreElements() Employee each = (Employee

37、) e.nextElement();result += each.getAnnualCost();return result;public int getHeadCount() return _staff.size();public Enumeration getStaff() return _staff.elements();public void addStaff(Party arg) _staff.addElement(arg);public String getName() return _name;private String _name;private Vector _staff

38、= new Vector();package generation.extractsuperclass;public class Employee extends Party public Employee(String name, String id, int annualCost) super(name);_id = id;_annualCost = annualCost;public int getAnnualCost() return _annualCost;public String getId() return _id;private int _annualCost;private

39、 String _id;package generation.extractsuperclass;public abstract class Party protected String _name;public String getName() return _name;public abstract int getAnnualCost();public Party(String _name) super();this._name = _name;5. 使用Eclipse AST设计并实现一个类信息统计小程序,可以统计一个类中方法的个数、属性的个数、源代码行数、代码行最多的方法名以及代码行数

40、、参数个数最多的方法名及其参数的个数等信息,并对实验项目中的类进行测试。将所实现程序的代码粘贴如下:/类信息统计程序源代码package test;import java.io.FileReader;import java.util.ArrayList;import java.util.LinkedList;import javax.management.remote.SubjectDelegationPermission;import javax.xml.parsers.ParserConfigurationException;import org.xml.sax.InputSource;i

41、mport org.xml.sax.SAXException;import ru.novosoft.uml.foundation.core.MAttribute;import ru.novosoft.uml.foundation.core.MClass;import ru.novosoft.uml.foundation.core.MGeneralization;import ru.novosoft.uml.foundation.core.MOperation;import ru.novosoft.uml.foundation.core.MParameter;import ru.novosoft

42、.uml.model_management.MModel;import ru.novosoft.uml.model_management.MPackage;import ru.novosoft.uml.xmi.XMIReader;public class Measure extends XMIReaderpublic Measure() throws SAXException, ParserConfigurationException super();/ TODO Auto-generated constructor stubpublic static void main(String arg

43、s) / TODO Auto-generated method stubMModel m_modelCurrent ;Measure measure = null; MPackage rtPackage; MClass rtClass = null; MOperation rtOperations = null; MAttributertAttributes = null; int operationNum=0; int attributNum=0; int noo=0; int noa=0; double si=0; int l=1; int temp=1; try measure = ne

44、w Measure(); catch (SAXException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (ParserConfigurationException e) / TODO Auto-generated catch blocke.printStackTrace();m_modelCurrent=measure.parse("examplesperson.xml");rtPackage=measure.getPackages(m_modelCurrent);for (int i

45、= 0; i < rtPackage.length; i+)rtClass=measure.getClass(rtPackagei);for(int i=0;i<rtClass.length;i+)temp=1;rtOperations=measure.getOperation(rtClassi);rtAttributes=measure.getAttribute(rtClassi);operationNum+=rtOperations.length;attributNum+=rtAttributes.length;/System.out.println(rtClassi+&quo

46、t;泛化关系"+rtClassi.getGeneralizations();/System.out.println(rtClassi+"关联关系"+rtClassi.getAssociationEnds();/for(int k=0;k<rtOperations.length;k+)/System.out.println(rtOperationsk+"参数"+rtOperationsk.getParameters();/MClass children=measure.getChildren(rtClassi); if (children!

47、=null)temp+; if(temp>l) l=temp; for(int j=0;j<children.length;j+)MOperationchildrenOperation=measure.getOperation(childrenj);/boolean added=false;for(int s=0;s<childrenOperation.length;s+)boolean overriden=false;if(childrenOperations.toString().equals(rtOperations0.toString() )MParameterrtP

48、arameters=measure.getParameter(rtOperations0);MParameterchildrenParameters=measure.getParameter(childrenOperations); for(int a=0;a<rtParameters.length;a+) for(int b=0;b<childrenParameters.length;b+) /System.out.println("父类方法参数"+rtParametersa+"子类方法参数"+childrenParametersb); i

49、f(!rtParametersa.toString().equals(childrenParametersb.toString() overriden=true; else noa+;if(overriden)noo+=1;/System.out.println("当前NOO"+noo); si=(double)(noa*l)/(double)operationNum;System.out.println("-"+m_modelCurrent+"-");System.out.println("一.LK度量结果如下:"

50、;);System.out.println("1.CS:Operation个数为"+operationNum+" Attribute个数为"+attributNum); System.out.println("2.NOA="+noa); System.out.println("3.NOO="+noo); System.out.println("4.SI="+si);System.out.println("二.CK度量结果如下:");System.out.println(&qu

51、ot;1.NOC: ");for(int i=0;i<rtClass.length;i+)MClass children=measure.getChildren(rtClassi); if (children!=null) System.out.print(" NOC("+rtClassi+")="+children.length); else System.out.print(" NOC("+rtClassi+")=0 "); System.out.println("n2.CBO: ");for(int i=0;i<rtClass.length;i+)System.out.print("

温馨提示

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

评论

0/150

提交评论