重构手法——对象结构优化类 | 类关系解耦 | 提取变量

52 阅读4分钟

简介

“提取变量”(Extract Variable)是一种基础且实用的代码重构手法。当代码中存在复杂的表达式时,这些表达式可能会使代码的可读性降低,理解和维护的难度增加。通过提取变量,我们可以将复杂的表达式拆分成更易理解的部分,将表达式的结果存储在一个有意义的变量中,从而使代码的意图更加清晰,提高代码的可读性和可维护性。

针对的症状(代码坏味道)

  • 复杂表达式:代码中存在包含多个运算符、函数调用或嵌套的复杂表达式,难以一眼看出其含义。
  • 重复表达式:相同的复杂表达式在代码中多次出现,不仅增加了代码的冗余度,还可能导致修改时出现遗漏。
  • 代码可读性差:复杂的表达式使得代码的逻辑难以理解,尤其是在调试和维护时,增加了开发人员的认知负担。

提取变量(Extract Variable)的详细步骤

  1. 识别复杂表达式
    • 在代码中找出那些包含多个运算符、函数调用或嵌套的复杂表达式,这些表达式可能会影响代码的可读性。
  2. 创建新变量
    • 为复杂表达式创建一个新的变量,变量名应能够清晰地描述表达式的含义。
  3. 赋值给新变量
    • 将复杂表达式的结果赋值给新创建的变量。
  4. 替换原始表达式
    • 在代码中用新变量替换原始的复杂表达式。
  5. 测试
    • 编译代码:确保代码编译通过,没有任何语法错误。
    • 运行测试:运行所有相关的单元测试,确保重构操作没有引入新的错误。
    • 手动测试:如果有必要,进行手动测试以验证功能的正确性。
  6. 代码审查
    • 同行评审:让同事或其他团队成员审查你的更改,确保代码质量和可维护性没有下降。
    • 文档更新:如果项目有维护文档的习惯,记得更新相关文档,说明提取变量的影响。

示例

假设有一个方法用于计算订单的税后总价,其中包含一个复杂的表达式。

原始代码

public class OrderCalculator {
    public double calculateTotal(double price, double taxRate) {
        return price + price * taxRate;
    }
}

重构步骤

  1. 识别复杂表达式price + price * taxRate 是一个复杂表达式,其含义不够直观。
  2. 创建新变量:创建一个名为 taxAmount 的变量,用于表示税费。
  3. 赋值给新变量:将 price * taxRate 赋值给 taxAmount
  4. 替换原始表达式:用 price + taxAmount 替换原始的复杂表达式。

重构后代码

public class OrderCalculator {
    public double calculateTotal(double price, double taxRate) {
        double taxAmount = price * taxRate;
        return price + taxAmount;
    }
}

练习

基础练习题

  1. 简单表达式提取

    • 给定以下 Java 代码,calculateArea 方法中包含一个复杂的表达式。请提取变量以提高代码的可读性。

      public class CircleAreaCalculator {
          public double calculateArea(double radius) {
              return Math.PI * radius * radius;
          }
      }
      
  2. 多步骤表达式提取

    • 下面的 Java 代码中,calculateDiscountPrice 方法有一个多步骤的复杂表达式。请提取变量来简化代码。
    public class DiscountCalculator {
        public double calculateDiscountPrice(double originalPrice, double discountRate, double shippingFee) {
            return originalPrice * (1 - discountRate) + shippingFee;
        }
    }
    

进阶练习题

  1. 重复表达式提取

    • 在这段 Java 代码中,calculateFinalScore 方法多次使用了相同的复杂表达式。请提取变量以消除重复。
          public class ScoreCalculator {
        public double calculateFinalScore(double score1, double score2, double weight1, double weight2) {
            return (score1 * weight1 + score2 * weight2) / (weight1 + weight2) + (score1 * weight1 + score2 * weight2) / (weight1 + weight2) * 0.1;
        }
    }
    
  2. 嵌套表达式提取

    • 给定以下 Java 代码,processData 方法包含嵌套的复杂表达式。请提取变量来提高代码的可读性。
    public class DataProcessor {
        public int processData(int value1, int value2, int value3) {
            return (value1 + value2) * (value2 + value3) / (value1 - value3);
        }
    }
    

综合拓展练习题

  1. 多表达式提取与代码审查模拟

    • 考虑一个简单的 Java 电商系统,有一个 Order 类,其中的 calculateTotalCost 方法包含多个复杂表达式。请对这些表达式进行提取变量的重构。
    • 假设你完成了重构,请模拟一份简单的代码审查报告,指出重构后的优点和可能存在的潜在问题。
    public class Order {
        private double productPrice;
        private double taxRate;
        private double shippingFee;
        private double discountRate;
    
        public Order(double productPrice, double taxRate, double shippingFee, double discountRate) {
            this.productPrice = productPrice;
            this.taxRate = taxRate;
            this.shippingFee = shippingFee;
            this.discountRate = discountRate;
        }
    
        public double calculateTotalCost() {
            return productPrice * (1 - discountRate) + productPrice * (1 - discountRate) * taxRate + shippingFee;
        }
    }