人人都会AI编程

3.3.3 代码重构优化

更新时间:2026-06-29

重构是在不改变代码外部行为的前提下,改善其内部结构,使代码更清晰、更易维护、更易扩展。重构不是重写,也不是修bug,而是持续优化设计的过程。

一、什么时候该重构

  • 重复代码:同一段逻辑出现在两处以上。
  • 过长函数:一个函数做了太多事,难以理解。
  • 过大类:类承担了过多职责,违反单一职责原则。
  • 参数列表过长:函数参数超过3~4个,难以使用。
  • 条件表达式过于复杂:if-else 嵌套深,逻辑不直观。
  • 代码坏味道:如数据泥团、霰弹式修改、依恋情结等。

二、常用重构手法(实用举例)

  1. 提炼函数

将复杂的代码块提取为独立函数,用函数名解释意图。

// 重构前
function printOwing(invoice) {
  console.log("---");
  console.log("Customer: " + invoice.customer);
  let outstanding = 0;
  for (let o of invoice.orders) {
    outstanding += o.amount;
  }
  console.log("Total: " + outstanding);
}

// 重构后
function printOwing(invoice) {
  printBanner();
  let outstanding = calculateOutstanding(invoice);
  printDetails(invoice.customer, outstanding);
}
function printBanner() { console.log("---"); }
function calculateOutstanding(invoice) {
  return invoice.orders.reduce((sum, o) => sum + o.amount, 0);
}
function printDetails(customer, total) {
  console.log("Customer: " + customer);
  console.log("Total: " + total);
}
  1. 引入参数对象

当一组参数总是一起传递时,用对象替代。

# 重构前
def create_appointment(start_date, start_time, end_date, end_time):
    ...

# 重构后
class TimeRange:
    def __init__(self, start, end):
        self.start = start
        self.end = end
def create_appointment(time_range):
    ...
  1. 以多态取代条件表达式

用类和多态替代复杂的switch或if-else。

// 重构前
double getSpeed(Animal a) {
    if (a.type == "bird") return a.baseSpeed - 5;
    else if (a.type == "fish") return a.baseSpeed + 2;
    else return a.baseSpeed;
}
// 重构后
abstract class Animal {
    abstract double getSpeed();
}
class Bird extends Animal {
    double getSpeed() { return baseSpeed - 5; }
}
class Fish extends Animal {
    double getSpeed() { return baseSpeed + 2; }
}
  1. 简化条件表达式
  • 合并条件:同一行为的不同条件合并为一个条件表达式。
  • 分解条件:将复杂的条件提取为独立函数,用名称解释含义。
  • 卫语句:处理特殊/异常情况后快速返回,减少嵌套。
// 卫语句示例
function getPayAmount() {
  if (isDead) return deadAmount();
  if (isSeparated) return separatedAmount();
  if (isRetired) return retiredAmount();
  return normalAmount();
}
  1. 搬移特性

将函数或字段移动到更合适的类或模块中,使职责内聚。例如,一个类频繁访问另一个类的数据,可将方法移到那个数据所在的类。

三、重构的安全步骤

  1. 确保有测试:重构前编写/运行单元测试,确保行为不变。
  2. 小步前进:每次只做一种重构,修改后立刻运行测试。
  3. 使用自动化工具:IDE重构功能(如重命名、提取函数、移动成员)可减少失误。
  4. 代码审查:提交前让同事审查,发现潜在问题。

四、真实场景建议

  • 不要为了重构而重构:总与添加功能或修复bug结合进行(“营地法则”)。
  • 优先重构高频修改的代码:修改越频繁,重构收益越大。
  • 保持提交原子化:一次重构一次提交,附带清晰说明,便于回溯。
  • 遗留代码先加测试再重构:没测试的遗留代码,先写特征测试固定住现有行为,再动手。

小结:重构是开发者每天都要做的事情。养成随时重构的习惯,用小的、安全的步骤持续优化代码,就能避免陷入“大重构”和“技术债务”的困境。