Code Fragment-相似功能放在一块

本文分析了Android源代码中GsmUmtsCallForwardOptions类的实现细节,展示了如何通过一致的顺序声明和初始化CallForwardEditPreference对象来管理呼叫转移选项。

下面是Android Source的packages/apps/Phone/src/com/android/phone/GsmUmtsCallForwardOptions.java里面的一段code。

package com.android.phone;

//省略一些代码

public class GsmUmtsCallForwardOptions extends TimeConsumingPreferenceActivity {

    //省略一些代码

    private static final String BUTTON_CFU_KEY   = "button_cfu_key";
    private static final String BUTTON_CFB_KEY   = "button_cfb_key";
    private static final String BUTTON_CFNRY_KEY = "button_cfnry_key";
    private static final String BUTTON_CFNRC_KEY = "button_cfnrc_key";

    private CallForwardEditPreference mButtonCFU;//note1:声明的一些顺序
    private CallForwardEditPreference mButtonCFB;
    private CallForwardEditPreference mButtonCFNRy;
    private CallForwardEditPreference mButtonCFNRc;

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        //省略一些代码

        mButtonCFU   = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFU_KEY);//note2:坚持了前面的顺序。
        mButtonCFB   = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFB_KEY);
        mButtonCFNRy = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFNRY_KEY);
        mButtonCFNRc = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFNRC_KEY);

        mButtonCFU.setParentActivity(this, mButtonCFU.reason);//note3:同种处理放在一起,形成强烈的类比
        mButtonCFB.setParentActivity(this, mButtonCFB.reason);//不同的处理块分开段落。
        mButtonCFNRy.setParentActivity(this, mButtonCFNRy.reason);
        mButtonCFNRc.setParentActivity(this, mButtonCFNRc.reason);

        mPreferences.add(mButtonCFU);
        mPreferences.add(mButtonCFB);
        mPreferences.add(mButtonCFNRy);
        mPreferences.add(mButtonCFNRc);
    }

    //省略了一些代码
}

代码中有这样的特点:

  • 声明的时候,有一定的声明顺序。
  • 使用的过程中坚持了这种顺序。
  • 相同的处理放在一起,凸显功能的一致性。
  • 不同处理段落隔开,说明逻辑的不同。(某些场景下可以表示一种先后顺延关系)


在软件开发过程中,重复代码(Duplicated Code)是常见的问题之一。它不仅增加了维护成本,还可能导致逻辑不一致和错误扩散。检测和消除重复代码是提升代码质量和可维护性的关键步骤。 ### 检测重复代码的方法 1. **静态代码分析工具** 使用专门的静态分析工具可以自动识别项目中的重复代码片段。这些工具通过比较代码结构、语法树或哈希值来判断相似性。例如: - **PMD CPD (Copy/Paste Detector)**:支持多种语言,通过词法分析识别重复代码块。 - **SonarQube**:集成CPD或其他重复检测算法,提供可视化报告并标注重复区域[^1]。 - **ReSharper / Roslynator (C#)**:适用于.NET生态,能够在IDE中实时提示重复代码。 - **JDeodorant / Duploc (Java)**:针对Java项目的重复检测与重构建议。 2. **基于抽象语法树(AST)的比对** 一些高级工具使用AST进行结构化比对,能够识别即使变量名不同但结构相同的代码段。这种方法更准确,适合复杂项目。 3. **代码克隆分类标准(Code Clone Types)** 根据重复程度可分为以下几类: - **Type-1 Clones**:完全相同的代码,仅注释或空白不同。 - **Type-2 Clones**:变量、常量不同,但结构相同。 - **Type-3 Clones**:结构部分变化,但逻辑高度相似。 工具通常会根据这些类型进行分类并给出详细报告[^1]。 4. **版本控制系统辅助分析** 利用Git等版本控制系统的日志信息,可以追踪哪些文件或模块频繁出现修改,从而定位潜在的复制粘贴行为。 5. **单元测试覆盖率监控** 如果多个测试用例覆盖了几乎相同的执行路径,则可能暗示底层实现存在冗余逻辑。 ### 消除重复代码的策略 1. **提取公共方法或类(Extract Method/Class)** 将重复的功能封装成独立的方法或类,供其他模块调用。这是最常见也是最有效的重构手段之一。 2. **模板方法模式(Template Method Pattern)** 当多个子类有相似的算法流程时,可以通过定义一个抽象基类来共享通用步骤,并允许子类重写特定部分。 3. **策略模式(Strategy Pattern)** 将一系列可互换的行为封装为独立的对象,使客户端可以在运行时切换不同的实现方式,避免条件分支过多导致的冗余。 4. **继承与多态** 对于具有共同接口的对象,利用面向对象特性减少重复逻辑,提高扩展性和复用率。 5. **函数式编程技术** 在支持高阶函数的语言中(如JavaScript、Python、Scala),可以将行为作为参数传递,从而简化重复操作。 6. **配置驱动设计** 将原本硬编码的规则抽取出来,以配置文件形式管理,使得更改无需修改源码即可生效。 7. **宏或预处理器指令** 在某些系统级编程场景下(如C/C++),合理使用宏定义可以帮助减少重复代码,但需谨慎以免影响可读性。 8. **自动化重构工具** 借助IDE内置功能或第三方插件(如IntelliJ IDEA的“Refactor This”、Visual Studio的Quick Actions)快速完成常见重构任务。 ### 示例:提取公共方法优化重复逻辑 假设存在如下两段相似代码: ```python def calculate_tax_us(income): return income * 0.25 def calculate_tax_uk(income): return income * 0.20 ``` 可以将其重构为: ```python def calculate_tax(income, rate): return income * rate # 调用示例 us_tax = calculate_tax(50000, 0.25) uk_tax = calculate_tax(45000, 0.20) ``` 这样不仅减少了代码行数,也提高了灵活性和可测试性。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值