本文目录导读:

我将为你展示几个典型的条件语句重构案例,从坏味道到好设计的完整对比。
卫语句取代嵌套条件(最经典)
❌ 原代码:深嵌套金字塔
public double getPayAmount() {
double result;
if (isDead) {
result = deadAmount();
} else {
if (isSeparated) {
result = separatedAmount();
} else {
if (isRetired) {
result = retiredAmount();
} else {
result = normalPayAmount();
}
}
}
return result;
}
✅ 重构后:卫语句提前返回
public double getPayAmount() {
if (isDead) return deadAmount();
if (isSeparated) return separatedAmount();
if (isRetired) return retiredAmount();
return normalPayAmount();
}
效果:嵌套从3层降为0层,逻辑主干一目了然。
条件表达式分解为函数
❌ 原代码:判断逻辑隐藏在一行大布尔表达式里
public double calculateDiscount(Order order, Customer customer) {
if (order.getTotal() > 1000
&& customer.getLoyaltyYears() > 2
&& customer.isVIP()
&& !order.deliveryIsUrgent()) {
return order.getTotal() * 0.2;
}
return order.getTotal() * 0.05;
}
✅ 重构后:提取描述性函数
public double calculateDiscount(Order order, Customer customer) {
if (isEligibleForBigDiscount(order, customer)) {
return order.getTotal() * 0.2;
}
return order.getTotal() * 0.05;
}
private boolean isEligibleForBigDiscount(Order order, Customer customer) {
return order.getTotal() > 1000
&& customer.hasLoyaltyYears(2)
&& customer.isVIP()
&& !order.deliveryIsUrgent();
}
以多态取代条件(策略模式)
❌ 原代码:switch 不断增长(违反开闭原则)
public class AnimalSound {
public void makeSound(String animalType) {
switch (animalType) {
case "Dog":
System.out.println("Woof");
break;
case "Cat":
System.out.println("Meow");
break;
case "Cow":
System.out.println("Moo");
break;
// 每新增一种动物,都要改这里
default:
throw new IllegalArgumentException("Unknown animal");
}
}
}
✅ 重构后:策略 + 工厂
public interface Animal {
void makeSound();
}
public class Dog implements Animal {
public void makeSound() { System.out.println("Woof"); }
}
public class Cat implements Animal {
public void makeSound() { System.out.println("Meow"); }
}
public class Cow implements Animal {
public void makeSound() { System.out.println("Moo"); }
}
public class SoundPlayer {
private Map<String, Animal> animalMap = new HashMap<>();
public void playSound(String type) {
Animal animal = animalMap.get(type);
if (animal != null) {
animal.makeSound();
} else {
throw new IllegalArgumentException("Unknown animal");
}
}
}
效果:新增动物时无需改动已有代码,只需新增类并注册到 Map。
合并重复的条件片段
❌ 原代码:相同代码在不同分支重复
public void process(Order order) {
if (order.isExpress()) {
System.out.println("计算运费...");
double fee = order.getWeight() * 3.5;
System.out.println("快速订单费用: " + fee);
sendConfirmation(order, "EXPRESS");
notifyWarehouse(order);
} else {
System.out.println("计算运费...");
double fee = order.getWeight() * 1.2;
System.out.println("普通订单费用: " + fee);
sendConfirmation(order, "NORMAL");
notifyWarehouse(order);
}
}
✅ 重构后:提取公共部分到末尾
public void process(Order order) {
double fee;
if (order.isExpress()) {
fee = order.getWeight() * 3.5;
System.out.println("快速订单费用: " + fee);
sendConfirmation(order, "EXPRESS");
} else {
fee = order.getWeight() * 1.2;
System.out.println("普通订单费用: " + fee);
sendConfirmation(order, "NORMAL");
}
// 公共部分提取到分支外
notifyWarehouse(order);
}
用对象代替开关(任务分发)
❌ 原代码:命令字符串判断
public void executeTask(String command, Context context) {
if (command.equals("send_email")) {
// 发送邮件逻辑(20行)
context.sendEmail(context.getUser().getEmail(), "Welcome!");
} else if (command.equals("generate_report")) {
// 生成报告逻辑(30行)
ReportGenerator.generate(context.getData());
} else if (command.equals("update_database")) {
// 更新数据库逻辑(15行)
DatabaseManager.update(context.getData());
}
// 20 个 if-else...
}
✅ 重构后:Command Pattern(命令模式)
public interface Command {
void execute(Context context);
}
public class SendEmailCommand implements Command {
public void execute(Context context) {
context.sendEmail(context.getUser().getEmail(), "Welcome!");
}
}
public class GenerateReportCommand implements Command {
public void execute(Context context) {
ReportGenerator.generate(context.getData());
}
}
public class UpdateDatabaseCommand implements Command {
public void execute(Context context) {
DatabaseManager.update(context.getData());
}
}
// 注册表
public class CommandRegistry {
private Map<String, Command> commands = new HashMap<>();
public CommandRegistry() {
commands.put("send_email", new SendEmailCommand());
commands.put("generate_report", new GenerateReportCommand());
commands.put("update_database", new UpdateDatabaseCommand());
}
public void execute(String command, Context context) {
Command cmd = commands.getOrDefault(command,
ctx -> { throw new UnsupportedOperationException(command); });
cmd.execute(context);
}
}
重构决策速查表
| 代码气味 | 重构手法 | 适用场景 |
|---|---|---|
| 嵌套过深 (3层+) | 卫语句 | 有大量提前返回机会 |
| 复杂布尔表达式 | 提取函数 | 条件可命名描述 |
| switch/if-else 频繁变化 | 多态/策略 | 分支类型稳定且明确 |
| 分支内重复代码 | 合并片段 | 重复代码不在分支逻辑中 |
| 命令字符串匹配 | 命令模式 | 有大量相似操作 |
核心原则:
- 代码可读性 > 代码行数(短不一定好)
- 意图表达 > 执行细节(名字比注释更重要)
- 开闭原则:对扩展开放,对修改封闭
如果你想看某个具体类型的重构(如金额计算、权限判断、状态流转),告诉我,我可以针对具体业务场景再给出示例。