简介
"用符号常量替换魔法数字"是提升代码可维护性的关键重构手法。通过将代码中直接使用的数字字面量替换为语义明确的常量,可以增强代码表达力并降低维护成本。
针对的症状(代码坏味道)
- 代码中出现难以理解含义的原始数字
- 同一数字在多处重复出现
- 需要根据业务需求调整数值
- 包含复杂数学计算的代码段
用符号常量替换魔法数字的详细步骤
- 识别魔法数字
- 查找代码中的原始数值
- 标记具有业务含义的数字
- 声明符号常量
- 使用全大写命名规范
- 添加必要的类型修饰符
- 替换引用点
- 用常量名替换原始数字
- 保持原有计算逻辑
- 验证重构
- 确保常量值符合业务需求
- 检查数值精度是否一致
示例
重构前代码:
class TaxCalculator {
double calculate(int income) {
return income * 0.15 + 500;
}
double luxuryTax(double price) {
return price > 1000000 ? price * 0.3 : 0;
}
}
重构步骤:
-
定义税率常量:
private static final double BASE_RATE = 0.15; private static final double LUXURY_THRESHOLD = 1_000_000; private static final double LUXURY_RATE = 0.3; private static final int TAX_DEDUCTION = 500; -
替换原始数值:
class TaxCalculator { private static final double BASE_RATE = 0.15; private static final double LUXURY_THRESHOLD = 1_000_000; private static final double LUXURY_RATE = 0.3; private static final int TAX_DEDUCTION = 500; double calculate(int income) { return income * BASE_RATE + TAX_DEDUCTION; } double luxuryTax(double price) { return price > LUXURY_THRESHOLD ? price * LUXURY_RATE : 0; } }
练习
基础练习题
-
简单数字替换
// 重构前 class Geometry { double sphereVolume(double r) { return (4.0 / 3.0) * 3.14159 * r * r * r; } }
进阶练习题
-
复合业务常量
// 重构前 class LoanService { boolean isHighRisk(Customer customer) { return customer.getAge() < 18 || customer.getIncome() < 2500; } }
综合拓展练习题
-
复杂公式重构
// 重构前 class Physics { double relativisticEnergy(double mass) { return mass * 299792458 * 299792458; } }
代码审查要点
-
优点:
- 增强数值的可解释性
- 集中管理关键参数
- 提升代码可测试性
-
潜在问题:
- 避免创建无意义常量
- 注意常量类型匹配
- 保持合理的常量可见域