重复代码重构建议工具DCRA详解
立即解锁
发布时间: 2025-08-20 00:44:57 阅读量: 1 订阅数: 4 


敏捷软件开发:从理论到实践的全面解析
# 重复代码重构建议工具 DCRA 详解
## 1. DCRA 重构技术
DCRA 提供了一系列的重构技术,用于处理重复代码,以下是这些重构技术的详细介绍:
| 重构技术 | 描述 |
| --- | --- |
| Extract method (EM) | 从一个方法中提取一部分语句作为一个新方法 |
| Replace method with method object (RMMO) | 即“提取工具类”,采用最简单的版本(具有公共属性和只有一个方法:构造函数的私有或受保护类) |
| Merge method (MM) | 删除一个方法的两个相同副本中的一个 |
| Pull up method (PUM) | 将一个方法移动到超类 |
| Pull up method object (PUMO) | “Pull up method”和“Replace method with method object”的组合 |
| Form template method (FTM) | 引入模板方法设计模式来管理子类中的行为变化 |
| Leave unchanged (LU) | 不进行任何重构 |
部分 Golomingi 和 Fowler 的重构建议未被包含在 DCRA 中,原因如下:
- “Substitute algorithm”:未考虑 Type - 4 克隆(以不同方式实现相同算法的代码片段)。
- “Push down method”:DCRA 目前不处理 SUPERCLASS 位置。
同时,在 Golomingi 的位置集合中添加了 SAME EXTERNAL SUPERCLASS 位置,它描述了所有位于扩展公共外部类(属于外部库的类)的兄弟类中的克隆。匿名类是 SAME EXTERNAL SUPERCLASS 实例的常见例子,因为它们通常扩展 Object 类。
## 2. 重复代码特征分析
### 2.1 克隆类型和粒度分布
通过对 50 个软件项目的分析,得到了不同位置的克隆类型和粒度分布,如下表所示:
| 位置 | Type - 1 # | Type - 1 % | Type - 3 # | Type - 3 % | Block # | Block % | Method # | Method % | 总数 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 祖先类 | 13 | 4.4 | 281 | 95.6 | 120 | 40.8 | 174 | 59.2 | 294 |
| 公共层次类 | 970 | 23.5 | 3152 | 76.5 | 968 | 23.5 | 3154 | 76.5 | 4122 |
| 一级堂兄弟类 | 416 | 12.2 | 2980 | 87.8 | 473 | 13.9 | 2923 | 86.1 | 3396 |
| 同一类 | 5645 | 9.9 | 51308 | 90.1 | 17096 | 30.0 | 39857 | 70.0 | 56953 |
| 同一外部超类 | 4384 | 6.2 | 66391 | 93.8 | 31534 | 44.6 | 39241 | 55.4 | 70775 |
| 同一方法 | 569 | 10.4 | 4901 | 89.6 | 5449 | 99.6 | 21 | 0.4 | 5470 |
| 兄弟类 | 2721 | 16.4 | 13868 | 83.6 | 2830 | 17.1 | 13759 | 82.9 | 16589 |
| 超类 | 91 | 8.4 | 981 | 91.6 | 431 | 40.2 | 641 | 59.8 | 1072 |
| 不相关类 | 2758 | 7.3 | 35035 | 92.7 | 23103 | 61.1 | 14690 | 38.9 | 37793 |
| 总计 | 17567 | 8.9 | 178897 | 91.1 | 82004 | 41.7 | 114460 | 58.3 | 196464 |
大部分(约 75%)克隆对属于表 2 中列出的位置。Type - 3 克隆对(有添加、删除或修改语句的代码片段)最为常见,因为代码片段复制时通常会有轻微修改。
### 2.2 克隆粒度选择
将检测到的克隆对分类为仅块克隆或方法克隆(块克隆包含两种情况)。平均而言,函数/方法克隆比块克隆更多,这支持了 Giesecke 选择函数/方法粒度的决策。方法是比块更具内聚性的单元,具有更高的可重用性。因此,DCRA 的检测过程配置为检测:
- Type - 1(仅允许空白差异的相同代码片段)和 Type - 3 克隆(有添加、删除或修改语句的代码片段)。
- 块级克隆,因为它们分布广泛且包含方法级克隆。
## 3. DCRA 工具组件及工作流程
### 3.1 DCRA 组件概述
DCRA 由四个组件组成:
- Clone Detector:检测克隆对的外部工具。
- Clone Detailer:分析 Clone Detector 的输出,添加所有必要的克隆对细节。
- Refactoring Advisor:为每个克隆对选择可能的重构技术。
- Refactoring Advice Aggregator:聚合有关克隆和重构的可用信息,按类或包分组,并按重构重要性或克隆对影响排序。
### 3.2 Clone Detector
选择 NiCad 作为克隆检测器,并进行如下参数设置:
- 选择块级粒度,以检测更易于管理的克隆。
- 最小克隆长度为 5 行,这是文献中常用的值。
- 代码片段之间的最大不相似度百分比为 30%(NiCad 的默认值)。
- 不允许重命名,仅检测 Type - 1 和相应的 Type - 3 子集。
- 将克隆分组为对,因为它们比 n 元组更易于管理。
### 3.3 Clone Detailer
该组件为克隆对添加选择重构技术所需的详细信息,包括:
- 每个克隆中使用的变量,根据其声明位置和使用情况进行标记。声明位置分类为:
1. 克隆内部。
2. 克隆外部但在其容器方法内。
3. 类属性。
4. 继承属性。
使用情况分类为:
1. 在克隆后但在其容器方法内使用。
2. 在克隆内读取。
3. 在克隆内修改。
- 每个克隆的长度、克隆行和不同行(NiCad 仅报告最长克隆的总长度)。
- 克隆对的位置。
- 克隆对的粒度:方法或块。
- 克隆对的类型:Type - 1 或 Type - 3。
### 3.4 工作流程 mermaid 图
```mermaid
graph LR
A[代码输入] --> B[Clone Detector]
B --> C[Clone Detailer]
C --> D[Refactoring Advisor]
D --> E[Refactoring Advice Aggregator]
E --> F[输出重构建议]
```
## 4. 重构技术选择与评估
### 4.1 耦合实体概念
引入“耦合实体”概念,当克隆访问其局部作用域(如容器类或方法)中的变量或属性,且重构将代码移动到不同作用域时,对这些变量或属性的引用可能会增加重构克隆的耦合级别。耦合实体因不同的重构类型而有不同评估,因为每种重构对代码应用不同的转换。
### 4.2 重构技术选择与排序
Refactoring Advisor 独立处理每个克隆对,步骤如下:
1. 根据克隆对的位置、粒度、类型和耦合实体,选择所有适用的重构技术。
2. 基于两个标准对所选技术进行排序:
- 相对 LOC 变化。
- 对 OOP(继承、多态和封装)的遵循程度。
重构评估分数的计算方式如下:
- 评估分数公式:$Evaluation=\frac{LOCV ar + OOP}{2}$
- LOC 变化公式:$LOCV ar=\frac{LOCBefore}{LOCAfter}-1$
- OOP 遵循程度公式:$OOP=\frac{Encap + Inh + Polym}{3}$
其中,$Encap$、$Inh$、$Polym$ 分别表示封装、继承和多态的评估值,取值范围为 $[-1, +1]$,分别对应最大可能恶化、无变化、最大改善。
以下是一个重构顾问计算示例:
| 重构技术 | 评估值 | OOP 遵循程度 | 封装 | 继承 | 多态 | LOC 变化 | LOC 前 | LOC 后 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| PUM | 0.66 | 0.33 | 0 | 1 | 0 | 1 | 10 | 5 |
| LU | -0.33 | -0.66 | 0 | -1 | -1 | 0 | 10 | 10 |
### 4.3 Refactoring Advice Aggregator
该组件总结所有建议和克隆对细节,为开发人员提供以下信息:
- 前 N 个最有效的重构。
- 前 N 个最有害的克隆对。
- 前 N 个最可重构的包和类。
- 前 N 个受影响最大的包和类。
目前 N 的值设置为 20。对于每个克隆对,仅考虑第一个重构(评估值最高的重构),并根据其克隆对长度(对中克隆的最大长度)对其权重进行归一化,以便不同重构应用的比较具有一致性。
## 5. 验证与结果
### 5.1 验证项目
对四个不同大小的项目进行了验证,项目信息如下表所示:
| 项目 | LOC | 克隆对数量 | 克隆 LOC | 克隆 LOC 百分比 |
| --- | --- | --- | --- | --- |
| fitjava - 1.1 | 3643 | 27 | 218 | 5.98 |
| jgrapht - 0.8.1 | 9086 | 53 | 736 | 8.10 |
| nekohtml - 1.9.14 | 6149 | 81 | 1130 | 18.38 |
| oscache - 2.4.1 | 5786 | 70 | 982 | 16.97 |
### 5.2 评估结果
Refactoring Advisor 为超过 80% 的克隆对提供了建议,所有重构建议都经过手动评估以验证其有用性。不同位置的评估结果如下表所示:
#### 同一类中的克隆评估结果
| 位置 | 类型 | EM | RMMO | MM | LU | 总数 |
| --- | --- | --- | --- | --- | --- | --- |
| SAME METHOD | 1 | 2/2 | 1/1 | 0/0 | 0/0 | 3/3 |
| | 3 | 8/10 | 0/0 | 0/0 | 33/33 | 41/43 |
| SAME CLASS | 1 | 6/6 | 0/0 | 0/0 | 0/0 | 6/6 |
| | 3 | 81/90 | 0/0 | 0/0 | 10/10 | 91/100 |
| 总计 | 1 | 8/8 | 1/1 | 0/0 | 0/0 | 9/9 |
| | 3 | 89/100 | 0/0 | 0/0 | 43/43 | 132/143 |
#### 兄弟类中的克隆评估结果
| 位置 | 类型 | PUM | PUMO | FTM | LU | 总数 |
| --- | --- | --- | --- | --- | --- | --- |
| SIBLING CLASS | 1 | 2/2 | 0/0 | 0/0 | 0/0 | 2/2 |
| | 3 | 0/2 | 0/0 | 1/2 | 0/0 | 1/4 |
| SAME EXTERNAL SUPERCLASS | 1 | 8/9 | 0/0 | 0/0 | 0/0 | 8/9 |
| | 3 | 0/0 | 0/3 | 8/25 | 0/0 | 8/28 |
| 总计 | 1 | 10/11 | 0/0 | 0/0 | 0/0 | 10/11 |
| | 3 | 0/2 | 0/3 | 9/27 | 0/0 | 9/32 |
### 5.3 结果分析
总体而言,产生建议的标准大多有效,主要提出了值得重构的重复代码。大多数情况下,建议的重构被接受,特别是“Extract method”、“Leave unchanged”、“Replace method with method object”。实际上,仅拒绝了 8% 的建议,这使得分析的软件系统中 66% 的重复代码得到了适当重构。
然而,某些类别的重构建议效果较差。例如,关于兄弟类之间 Type - 3 克隆对的 9/32 个重构建议实际上不值得应用,“Form template method”常因克隆行数太少而被拒绝,这种情况下通常首选“Pull up method”。同一类中的 Type - 3 克隆对也存在类似问题,低排名的重构因克隆规模小而往往不值得应用。此外,“Replace method with method object”和“Pull up method object”重构技术很少被建议,因为它们非常耗费代码行。
## 6. 总结与展望
### 6.1 总结
该技术可以根据代码的不同属性,为代码克隆提供最佳的重构建议,帮助开发者进行重复代码的重构,提高设计质量,增强代码的可管理性,减少代码检查阶段花费的时间。
采用基于场景的方法,根据克隆对的位置对其进行分类,为每个位置提供一组可能的重构技术,减少了重复代码重构过程中的人工参与。扩展了现有的分类类别,能够自动为大量原本难以处理的重复代码提供重构建议。
### 6.2 未来工作
- 扩展 DCRA 以处理所有剩余的位置。
- 细化参数设置,特别是最小克隆长度和最小不相似度百分比。
- 对 Clone Detailer 进行增强,跟踪读取或修改的耦合实体,为重构决策提供更详细的线索。
- 考虑除克隆对之外的克隆组。
- 研究代码克隆重构对不同软件质量指标的影响,以确定需要移除的克隆的优先级。
## 7. DCRA 重构技术的优势与挑战
### 7.1 优势
DCRA 的重构技术具有多方面优势,以下为详细介绍:
- **全面性**:提供了多种重构技术,如 Extract method、Replace method with method object 等,能应对不同场景下的重复代码问题。例如在处理同一类中的重复代码时,Extract method 可将重复代码提取为新方法,提高代码复用性。
- **智能评估**:通过 LOC 变化和 OOP 原则遵循程度两个标准对重构技术进行评估和排序,能为开发者提供更科学的重构建议。如在示例中,根据评估分数可清晰看出不同重构技术的优劣。
- **适用性广**:对不同类型(Type - 1 和 Type - 3)、不同粒度(块级和方法级)的克隆都能进行处理,且能适应不同位置的克隆,包括同一类、兄弟类、同一外部超类等。
### 7.2 挑战
尽管 DCRA 有诸多优势,但也面临一些挑战:
- **部分重构技术成本高**:像“Replace method with method object”和“Pull up method object”,由于非常耗费代码行,很少被建议使用,限制了其应用范围。
- **克隆规模影响重构效果**:对于 Type - 3 克隆,特别是克隆行数较少的情况,如同一类中或兄弟类之间的小克隆,一些重构建议可能不值得应用,影响了重构的有效性。
- **参数设置需优化**:目前的参数设置,如最小克隆长度和最小不相似度百分比,还需要进一步细化,以提高 DCRA 的性能和准确性。
## 8. DCRA 与其他重构工具的比较
### 8.1 与传统重构工具对比
传统重构工具可能缺乏对克隆位置、类型和粒度的详细分类,而 DCRA 基于场景的方法,根据克隆对的位置进行分类,为每个位置提供特定的重构技术建议,更具针对性。例如,对于同一外部超类位置的克隆,传统工具可能难以处理,而 DCRA 能提供有效的重构方案。
### 8.2 与其他克隆检测工具对比
一些克隆检测工具可能仅专注于克隆的检测,而 DCRA 不仅能检测克隆,还能提供重构建议,并对重构技术进行评估和排序。如 NiCad 作为克隆检测器,仅完成了检测任务,而 DCRA 的其他组件能进一步处理克隆并提供解决方案。
## 9. DCRA 的应用案例分析
### 9.1 案例一:fitjava - 1.1 项目
在 fitjava - 1.1 项目中,DCRA 为 27 个克隆对提供了重构建议。经过验证,大部分建议被接受,有效减少了重复代码。例如,对于同一类中的 Type - 3 克隆,采用 Extract method 重构技术,将重复代码提取为新方法,提高了代码的可维护性。
### 9.2 案例二:jgrapht - 0.8.1 项目
jgrapht - 0.8.1 项目有 53 个克隆对,Refactoring Advisor 根据克隆对的位置、粒度和类型,选择了合适的重构技术。如对于兄弟类之间的克隆,优先选择 Pull up method 重构技术,将方法提升到超类,增强了代码的复用性。
### 9.3 案例分析总结
通过对不同项目的应用案例分析,可以看出 DCRA 在不同规模和复杂度的项目中都能发挥作用,为开发者提供有效的重构建议,提高代码质量。但也发现了一些问题,如部分重构技术在小克隆场景下效果不佳,需要进一步优化。
## 10. 提升 DCRA 性能的策略
### 10.1 参数优化策略
- **最小克隆长度调整**:根据不同项目的特点,适当提高最小克隆长度,避免对过小的克隆进行不必要的重构。例如,对于大型项目,可将最小克隆长度设置为 8 行或更高。
- **最小不相似度百分比调整**:根据项目的代码风格和需求,调整最小不相似度百分比,以更准确地检测和处理克隆。如对于代码变化较大的项目,可适当提高该百分比。
### 10.2 耦合实体处理策略
加强对耦合实体的管理和分析,在重构前更准确地评估耦合实体对重构的影响。例如,对于耦合度较高的克隆,可先对耦合实体进行处理,再进行重构,以降低重构风险。
### 10.3 技术改进策略
- **引入机器学习算法**:利用机器学习算法对重构建议进行优化,根据历史数据和项目特点,自动调整重构技术的评估和排序。
- **扩展重构技术**:研究和开发新的重构技术,以应对更复杂的重复代码问题,提高 DCRA 的处理能力。
## 11. DCRA 未来发展趋势
### 11.1 集成更多功能
未来 DCRA 可能会集成更多功能,如与代码审查工具集成,在代码审查过程中自动检测和提示重复代码及重构建议;与版本控制系统集成,在代码提交时自动检查重复代码并提供重构方案。
### 11.2 支持更多编程语言
目前 DCRA 主要针对 Java 语言,未来可能会扩展支持更多编程语言,如 Python、C++ 等,以满足不同开发者的需求。
### 11.3 与人工智能结合
借助人工智能技术,进一步提高 DCRA 的智能性和自动化程度。例如,利用自然语言处理技术理解开发者的需求,提供更符合开发者意图的重构建议。
## 12. DCRA 使用建议
### 12.1 前期准备
- **代码标准化**:在使用 DCRA 前,对代码的行尾字符进行标准化处理,确保能进行精确的行计数,从而更准确地评估重构效果。
- **参数设置**:根据项目的特点和需求,合理设置 DCRA 的参数,如最小克隆长度和最小不相似度百分比。
### 12.2 重构过程
- **参考评估结果**:在选择重构技术时,参考 DCRA 提供的评估分数,优先选择评估分数高的重构技术。
- **注意克隆规模**:对于克隆行数较少的情况,谨慎选择重构技术,避免不必要的重构。
### 12.3 后期验证
- **手动评估**:对 DCRA 提供的重构建议进行手动评估,确保重构建议的有效性和可行性。
- **持续优化**:根据重构后的效果,不断优化 DCRA 的参数设置和重构策略,提高 DCRA 的性能。
### 12.4 工作流程 mermaid 图
```mermaid
graph LR
A[前期准备] --> B[运行 DCRA]
B --> C[获取重构建议]
C --> D[参考评估结果选择重构技术]
D --> E[进行重构]
E --> F[后期验证]
F --> G{是否满意}
G -- 是 --> H[结束]
G -- 否 --> I[持续优化参数和策略]
I --> B
```
## 13. 总结
DCRA 作为一款重复代码重构建议工具,通过多种重构技术和智能评估机制,为开发者提供了有效的重复代码解决方案。虽然面临一些挑战,但通过不断优化参数设置、改进技术和扩展功能,有望在未来发挥更大的作用。开发者在使用 DCRA 时,应充分了解其优势和局限性,按照合理的流程进行操作,以提高代码质量和开发效率。
0
0
复制全文
相关推荐










