3901110721李奇软件配置管理实验报告3Word下载.docx

上传人:b****5 文档编号:18829934 上传时间:2023-01-01 格式:DOCX 页数:38 大小:26.29KB
下载 相关 举报
3901110721李奇软件配置管理实验报告3Word下载.docx_第1页
第1页 / 共38页
3901110721李奇软件配置管理实验报告3Word下载.docx_第2页
第2页 / 共38页
3901110721李奇软件配置管理实验报告3Word下载.docx_第3页
第3页 / 共38页
3901110721李奇软件配置管理实验报告3Word下载.docx_第4页
第4页 / 共38页
3901110721李奇软件配置管理实验报告3Word下载.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

3901110721李奇软件配置管理实验报告3Word下载.docx

《3901110721李奇软件配置管理实验报告3Word下载.docx》由会员分享,可在线阅读,更多相关《3901110721李奇软件配置管理实验报告3Word下载.docx(38页珍藏版)》请在冰豆网上搜索。

3901110721李奇软件配置管理实验报告3Word下载.docx

专业4:

一、实验目的

1.熟悉常用的代码味道的涵义和特征;

2.熟悉常用的代码重构手段;

3.学会使用常用重构手段对常见代码味道进行重构;

4.掌握一种代码味道识别工具(CSDT);

5.熟悉Eclipse重构菜单;

6.学会使用EclipseAST来解析Java源代码;

7.设计并实现两种代码味道的自动识别方法;

8.设计并实现一种代码味道的自动重构方法。

二、实验内容

1.根据常见代码味道的特点,选取合适的重构手段对它们进行重构,填写相应的表格;

2.掌握一款代码味道识别工具,并使用该工具对至少一个实验项目进行代码味道识别,寻找存在代码味道的类和代码片段;

【参考资料:

七款代码味道识别工具

3.学习使用Eclipse重构(Refactor)菜单,从实验项目中选取合适的代码进行重构操作;

4.自学EclipseAST,包括获取、访问、创建和修改AST等操作;

【EclipseAST学习资料:

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(提炼函数)

如果在参数列中看到基本类型的数据:

IntroduceParameterObject(引入参数对象)

发现自己正从数组中挑选数据:

ReplaceArraywithObject(以对象取代数组)

纯稚的数据类(DataClass)

对于public字段:

EncapsulateField(封装字段)

如果一个类内含容器类的字段,如果没有得到恰当的封装:

EncapsulateCollection(封装集合)

对于那些不该被其他类修改的字段:

RemoveSettingMethod(移除设值函数)

找出Getter/Setter函数被其他类运用的地点:

MoveMethod(搬移函数)

如果无法搬移整个函数:

ExtractMethod(提炼函数)

将Getter/Setter函数隐藏起来:

HideMethod(隐藏函数)

重复代码(DuplicatedCode)

同一个类的一个/两个方法含有相同的代码:

ExtractMethod(提炼函数)

两个互为兄弟的子类含有相同的代码:

ExtractMethod(提炼函数)、PullUpMethod(函数上移)、FormTemplateMethod(塑造模板函数)

两个毫不相关的类含有相同的代码:

ExtractClass(提炼类)

异曲同工的类(AlternativeClasseswithDifferentInterfaces)

两个函数做同一件事,却有着不同的签名:

RenameMethod(函数改名)

将某些行为移入类,直到两者的协议一致为止:

必须重复而冗赘地移入代码:

ExtractSuperclass(提炼超类)

Switch惊悚现身(SwitchStatement)

与类型码相关的函数或类:

ExtractMethod(提炼函数)、MoveMethod(搬移函数)、ReplaceConditionalwithPolymorphism(以多态取代条件表达式)、ReplaceTypeCodewithSubclass(以子类取代类型码)、ReplaceTypeCodewithState/Strategy(以State/Strategy取代类型码)

只在单一函数中有一些选择事件,且不想改动它们:

ReplaceParameterwithExplicitMethods(以明确函数取代参数)

选择条件之一是null:

IntroduceNullObject(引入Null对象)

令人迷惑的暂时字段(TemporaryField)

一个对象中某个实例变量仅为某种特定情况而定:

在“变量不合法”的情况下创建一个Null对象,从而避免写出条件式代码:

被拒绝的遗赠(RefusedBequest)

子类不想或不需要继承超类(先为子类新建一个兄弟类):

ExtractSubclass(提炼子类)、PushDownMethod(函数下移)、PushDownField(字段下移)

子类复用了超类的行为(实现),却又不愿意支持超类的接口,拒绝继承超类的实现:

ReplaceInheritancewithDelegation(以委托取代继承)

数据泥团(DataClumps)

两个类中有相同的字段、许多函数签名中的参数相同:

缩短参数列表、简化函数调用:

IntroduceParameterObject(引入参数对象)、PreserveWholeObject(保持对象完整)

狎昵关系(InappropriateIntimacy)

类之间的关系过于亲密:

MoveMethod(搬移函数)、MoveField(搬移字段)、ChangeBidirectionalAssociationtoUnidirectional(将双向关联改为单向关联)

如果两个类存在共同点:

ExtractClass(提炼类)、HideDelegate(隐藏“委托关系”)

从继承体系中分离子类:

冗赘类(LazyClass)

对于几乎没用的组件:

InlineClass(将类内联化)

如果某些子类没有做足够的工作:

CollapseHierarchy(折叠继承体系)

依恋情结(FeatureEnvy)

函数对某个类的兴趣高过对自己所处类的兴趣:

MoveMethod(搬移函数)、MoveField(搬移字段)

函数中只有一部分对其他类更感兴趣:

ExtractMethod(提炼函数)、MoveMethod(搬移函数)

判断哪个类拥有最多被此函数使用的数据,然后就把这个函数和那些数据放在一起

过度耦合的消息链(MessageChains)

a.getB().getC().getD().getE()……

存在一长串getThis()或一长串临时变量:

HideDelegate(隐藏“委托关系”)

中间人(MiddleMan)

过度运用委托(一半及以上的函数都委托给其他类):

RemoveMiddleMan(移除中间人)

如果“不干实事”的函数只有少数几个:

InlineMethod(内联函数)

如果中间人还有其他行为,需要对原对象的行为进行扩展:

ReplaceDelegationwithInheritance(以继承取代委托)

发散式变化(DivergentChange)

如果某个类经常因为不同的原因在不同的方向上发生变化【找出某特定原因而造成的所有变化】:

霰弹式修改(ShotgunSurgery)

把所有需要修改的代码放进同一个类中:

如果眼下没有合适的类可以安置这些代码,就创造一个

把一系列相关行为放进同一个类中:

平行继承体系(ParallelInheritanceHierarchies)

让一个继承体系的实例引用另一个继承体系的实例:

不完美的库类(IncompleteLibraryClass)

如果只想修改库类的一两个函数:

IntroduceForeignMethod(引入外加函数)

如果想要添加一大堆额外行为:

IntroduceLocalExtension(引入本地扩展)

过长参列()

向已有对象发出一条请求就可以取代一个参数:

ReplaceParameterwithMethod(以函数取代参数)

参数缺乏合理的对象归属:

IntroduceParameterObject(引入参数对象)

将来自同一个对象的一堆参数收集起来:

PreserveWholeObject(保持对象完整)

夸夸其谈的未来性(SpeculativeGenerality)

某个抽象类没有太大作用:

不必要的委托:

函数的某些参数未被使用:

RemoveParameter(移除参数)

函数名称带有多余的抽象涵义:

对于无用的函数:

InlineMethod(内联函数)、RemoveMethod(移除函数)

2.选取一款代码味道识别工具和实验项目进行代码味道识别实验,记录如下信息:

(1)代码味道检测工具名称:

PMD

(2)实验项目名称【至少1个】:

happychatroom

(3)实验结果:

代码味道数量

代码味道实例【类名或者代码片段,如果存在该代码味道的话至少需提供1个实例】

重复代码

134

Founda95line(286tokens)duplicationinthefollowingfiles:

Startingatline52ofC:

\软件配置实验\《软件配置管理\HappyChatRoom\src\cn\csu\chatRoom\controller\net\server\ServerFrame.java

Startingatline62ofC:

\软件配置实验\《软件配置管理\HappyChatRoom\src\cn\csu\chatRoom\src\Test\ServerFrame.java

ServerTransactiontransact=newServerTransaction();

/**

*Auto-generatedmainmethodtodisplaythisJFrame

*/

publicstaticvoidmain(String[]args){

SwingUtilities.invokeLater(newRunnable(){

publicvoidrun(){

ServerFrameinst=newServerFrame();

inst.setLocationRelativeTo(null);

inst.setVisible(true);

inst.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

});

}

publicServerFrame(){

super("

服务端"

);

initGUI();

privatevoidinitGUI(){

try{

setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

{

jPanel1=newJPanel();

getContentPane().add(jPanel1,BorderLayout.CENTER);

jPanel1.setLayout(null);

{

jTextField1=newJTextField();

jPanel1.add(jTextField1);

jTextField1.setBounds(47,199,187,24);

jTextField1.addActionListener(this);

}

jButton1=newJButton();

jPanel1.add(jButton1);

jButton1.setText("

\u91cd\u65b0\u6765\u4e00\u6b21"

jButton1.setBounds(294,199,74,24);

jButton1.addActionListener(this);

jButton2=newJButton();

jPanel1.add(jButton2);

jButton2.setText("

\u5173\u95ed\u7ebf\u7a0b"

jButton2.setBounds(294,164,62,24);

jButton2.addActionListener(this);

jScrollPane1=newJScrollPane();

jPanel1.add(jScrollPane1);

jScrollPane1.setBounds(47,30,316,114);

{

jTextPane1=newJTextPane();

jScrollPane1.setViewportView(jTextPane1);

jTextPane1.setBounds(46,30,313,111);

jTextPane1.setEditable(false);

}

pack();

setSize(400,300);

}catch(Exceptione){

e.printStackTrace();

}

privatevoidreSetUp(){

server=newServerSocket(8765);

insert("

SetUP!

Waitforyou.."

listenT.start();

}catch(UnknownHostExceptione){

//TODOAuto-generatedcatchblock

}catch(IOExceptione){

3.使用EclipseRefactor菜单,掌握一些常用的重构操作,并在实验项目中选取合适的代码实施重构,填写如下表格:

重构名称

重构之前代码

重构之后代码

Rename

PublicclassChatRecordOper{

publicChatRecordOper(Stringpath){

}

publicvoidwrite(Stringt){

publicclassChatRecord{

publicChatRecord(Stringpath){

publicvoidwrite(Stringt){

Move

PrivatedoublegetCharge(doublepriceAmount,Purchasepurchase){

Returnpurchase.getCharge(priceAmount);

PublicclassPurchase{

PrivateBookbook;

Purchase(Bookbook){

This.book=book;

PublicBookgetBook(){

Returnthis.book;

PublicdoublegetCharge(doublepriceAmount){

priceAmount+=(float)getBook().getBookPrice()*getBook().getDiscount();

ReturnpriceAmount;

ChangeMethodSignature

PublicChatRecord(Stringpath){

publicChatRecord(Stringpath){

publicvoidwriter(Stringt){

Extracemethod

publicstaticvoidsetForeground(JEditorPaneeditor,Colorfg){

if(editor!

=null){

if(fg!

MutableAttributeSetattr=newSimpleAttributeSet();

StyleConstants.setForeground(attr,fg);

setCharacterAttributes(editor,attr,false);

}else{

UIManager.getLookAndFeel().provideErrorFeedback(editor);

setGround(editor,fg);

privatestaticvoidsetGround(JEditorPaneeditor,Colorfg){

StyleConstants.setForeground(

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 设计艺术

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1