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

81 阅读4分钟

简介

“内联变量”(Inline Variable)是一种重构手法,通过将不必要的变量直接替换为其值或表达式,从而简化代码并提高可读性。这种方法适用于那些变量名并没有提供额外信息,或者变量只被使用一次的情况。

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

  • 不必要的临时变量(Unnecessary Temporary Variable)
  • 变量名没有提供额外信息(Variable Name Does Not Add Meaning)
  • 变量只被使用一次(Variable Used Only Once)

内联变量(Inline Variable)的详细步骤

  1. 识别需要内联的变量
    • 查找只被使用一次的变量:在代码中找到那些只被使用一次的变量。
    • 评估变量的必要性:确认这些变量是否真的有必要存在,或者它们的值是否可以直接替换到使用它们的地方。
  2. 替换变量
    • 直接替换变量:将变量的使用处直接替换为其值或表达式。
    • 删除变量声明:删除不再需要的变量声明。
  3. 测试
    • 编译代码:确保代码编译通过,没有任何语法错误。
    • 运行测试:运行所有相关的单元测试,确保重构操作没有引入新的错误。
    • 手动测试:如果有必要,进行手动测试以验证功能的正确性。
  4. 代码审查
    • 同行评审:让同事或其他团队成员审查你的更改,确保代码质量和可读性没有下降。
    • 文档更新:如果项目有维护文档的习惯,记得更新相关文档,说明内联变量的影响。

示例

假设有一个方法 calculateTotal,其中包含一个不必要的临时变量,我们希望对其进行“内联变量”的重构:

public class Order {
   private double price;
   private int quantity;

   public double calculateTotal() {
      double subTotal = price * quantity;
      return subTotal;
   }
}

步骤如下:

  1. 识别需要内联的变量:

    • 不必要的临时变量: double subTotal = price * quantity;
  2. 替换变量:

    • 直接替换变量:将 return subTotal; 替换为 return price * quantity;
    • 删除变量声明:删除 double subTotal = price * quantity;
  3. 替换后的代码:

       public class Order {
       private double price;
       private int quantity;
    
       public double calculateTotal() {
          return price * quantity;
       }
    }
    
  4. 测试:

    • 编译代码:确保代码编译通过,没有任何语法错误。
    • 运行测试:运行所有相关的单元测试,确保重构操作没有引入新的错误。
  5. 代码审查:

    • 让同事审查代码,确保没有引入新的问题。

练习

基础练习题

  1. 内联不必要的临时变量
    • 给定以下 Java 代码,calculateDiscount方法中有一个不必要的临时变量discountAmount。请将其内联。

        public class DiscountCalculator {
         private double price;
         private double discountRate;
      
         public DiscountCalculator(double price, double discountRate) {
            this.price = price;
            this.discountRate = discountRate;
         }
      
         public double calculateDiscount() {
            double discountAmount = price * discountRate;
            return discountAmount;
         }
      }
      
  2. 内联只使用一次的变量
    • 下面的 Java 代码中,calculateTotal方法中有一个只使用一次的变量totalPrice。请将其内联。

        public class Order {
         private double price;
         private int quantity;
      
         public double calculateTotal() {
            double totalPrice = price * quantity;
            return totalPrice;
         }
      }
      

进阶练习题

  1. 内联复杂表达式中的变量
    • 在这段 Java 代码中,calculateFinalPrice方法内有一个复杂表达式中的变量discountedPrice。请将其内联。

        public class PriceCalculator {
         private double price;
         private double discountRate;
         private double taxRate;
      
         public PriceCalculator(double price, double discountRate, double taxRate) {
            this.price = price;
            this.discountRate = discountRate;
            this.taxRate = taxRate;
         }
      
         public double calculateFinalPrice() {
            double discountedPrice = price * (1 - discountRate);
            return discountedPrice * (1 + taxRate);
         }
      }
      
  2. 内联方法与返回值处理
    • 给定以下 Java 代码,processData方法包含一个只使用一次的变量processedData。请将其内联。

        import java.util.ArrayList;
      import java.util.List;
      
      public class DataProcessor {
         public int processData(int[] dataArray) {
            List<Integer> processedData = transformData(dataArray);
            return calculateSum(processedData);
         }
      
         private List<Integer> transformData(int[] dataArray) {
            List<Integer> processedData = new ArrayList<>();
            for (int num : dataArray) {
               num = num * 2;
               if (num > 10) {
                  num = num - 5;
               }
               processedData.add(num);
            }
            return processedData;
         }
      
         private int calculateSum(List<Integer> processedData) {
            int sum = 0;
            for (int num : processedData) {
               sum += num;
            }
            return sum;
         }
      }
      

综合拓展练习题

  1. 多模块内联与代码审查模拟
    • 考虑一个简单的 Java 电商系统,有Product类、Cart类和Order类。Cart类中的calculateCartTotal方法和Order类中的calculateOrderTotal方法都有不必要的临时变量。

    • 请对这些方法进行 “内联变量” 重构,将不必要的临时变量内联。

    • 假设你完成了重构,请模拟一份简单的代码审查报告,指出重构后的优点和可能存在的潜在问题。

        class Product {
         private double price;
      
         public Product(double price) {
            this.price = price;
         }
      
         public double getPrice() {
            return price;
         }
      }
      
      class Cart {
         private Product[] products;
         private double discountRate;
      
         public Cart(Product[] products, double discountRate) {
            this.products = products;
            this.discountRate = discountRate;
         }
      
         public double calculateCartTotal() {
            double total = 0;
            for (Product product : products) {
               total += product.getPrice();
            }
            return total * (1 - discountRate);
         }
      }
      
      class Order {
         private Product[] products;
         private double shippingCost;
      
         public Order(Product[] products, double shippingCost) {
            this.products = products;
            this.shippingCost = shippingCost;
         }
      
         public double calculateOrderTotal() {
            double total = 0;
            for (Product product : products) {
               total += product.getPrice();
            }
            return total + shippingCost;
         }
      }