理解重构的本质
重构不是简单的代码整理,而是一种系统的、可控的代码改进过程。其核心是在不改变外部行为的前提下,改善代码结构。
重构的关键原则
1. 安全第一:测试驱动
重构前确保有可靠的测试覆盖
小步前进,频繁验证
保持代码始终处于可运行状态
2. 识别"坏味道"
掌握这些常见代码问题:
结构和理解性问题:
过长函数(>20行)
过大类(职责过多)
过长参数列表
重复代码
过度复杂的条件逻辑
关系问题:
特性依恋(类过度使用其他类的数据)
数据泥团(总是一起出现的字段)
不恰当的亲密关系(类之间过度耦合)
命名问题:
模糊的命名
不一致的术语
误导性名称
重构技巧库
基础重构技巧
提取函数/方法
// 重构前 function processOrder(order) { // 验证逻辑... // 计算价格逻辑... // 库存检查逻辑... // 发货处理逻辑... } // 重构后 function processOrder(order) { validateOrder(order); calculatePrice(order); checkInventory(order); processShipping(order); }内联函数(反向操作)
当函数体比函数名更清晰时使用
变量改名
// 坏 let d = new Date(); // 什么意思? // 好 let currentDate = new Date(); let orderCreationDate = new Date();引入解释性变量
// 重构前 if (price > 100 && quantity < 10 && isPremiumCustomer) { // ... } // 重构后 const isExpensiveItem = price > 100; const isLowStock = quantity < 10; const eligibleForDiscount = isExpensiveItem && isLowStock && isPremiumCustomer;
中级重构技巧
分解条件表达式
// 重构前 function getShippingCost(order) { if (order.country === "US") { if (order.weight > 10) return 20; return 10; } else if (order.country === "CA") { return 15; } else { return 25; } } // 重构后 function getShippingCost(order) { const shippingRules = { US: (weight) => weight > 10 ? 20 : 10, CA: () => 15, default: () => 25 }; const rule = shippingRules[order.country] || shippingRules.default; return rule(order.weight); }合并重复代码片段
识别并统一重复的逻辑
但注意不要过度抽象
以多态取代条件表达式
// 重构前 class Bird { getSpeed(type) { switch(type) { case "EUROPEAN": return 10; case "AFRICAN": return 20; case "NORWEGIAN_BLUE": return 30; } } } // 重构后 class Bird { getSpeed() { return 0; } } class EuropeanBird extends Bird { getSpeed() { return 10; } }
高级重构技巧
引入参数对象
// 重构前 function createUser(name, email, phone, address, city, zip) { // ... } // 重构后 function createUser(userData) { // userData: { name, email, phone, address, city, zip } }提取类/合并类
当一个类承担太多职责时拆分成多个
当多个类高度耦合时考虑合并
以查询取代临时变量
// 重构前 function calculateTotal(order) { const basePrice = order.price * order.quantity; const discount = Math.max(0, order.quantity - 5) * order.price * 0.1; return basePrice - discount; } // 重构后 function calculateTotal(order) { return basePrice(order) - discount(order); } function basePrice(order) { return order.price * order.quantity; }
重构工作流
1. 分析阶段
识别需要重构的代码区域
理解现有代码的功能和行为
建立测试安全网
2. 执行阶段
选择适当的重构技巧
小步前进,频繁测试
保持每次修改的独立性
3. 验证阶段
运行所有测试
检查代码质量指标
确保没有引入回归问题
重构的"不"原则
不要在没有测试时大规模重构
不要同时重构和添加新功能
不要为了重构而重构
不要过度设计
不要忽视团队共识
实用工具和指标
代码质量指标
圈复杂度(建议 < 10)
认知复杂度
重复代码百分比
代码覆盖率(目标 > 80%)
重构工具
IDE内置重构功能(VS Code, IntelliJ IDEA等)
静态分析工具(ESLint, SonarQube)
测试框架(Jest, Mocha, PyTest等)
重构心态
代码是负债,不是资产
代码需要维护成本
更少的代码通常更好
童子军规则
离开营地时比发现时更干净
每次修改都做微小改进
迭代思维
重构是持续过程,不是一次性事件
允许代码逐渐演化
重构决策框架
当面对重构选择时,问自己:
当前代码的问题是什么?
不改动会有什么后果?
重构的成本是多少?
期望的收益是什么?
是否有更简单的方法?
最好的重构是让代码变得简单、清晰、可读,而不是追求完美的架构。代码首先是给人读的,其次才是给机器执行的。