重构if/else代码的实战技巧与设计模式应用

重构if/else代码的实战技巧与设计模式应用 1. 重构if/else代码的实战指南作为一名经历过多次大型系统重构的老码农我深知if/else堆积如山的痛苦。上周刚接手一个老项目光是登录模块就有27层嵌套if看得我血压飙升。今天就分享几种我实战验证过的重构方案帮你把屎山变成可维护的代码。重要提示重构前务必确保有完善的单元测试覆盖否则很容易改出线上事故2. 基础优化技巧2.1 提前return的艺术新手最容易犯的错误就是无脑使用if/else结构。看这段典型代码if (user ! null) { if (user.isVip()) { if (order.getAmount() 100) { // 核心业务逻辑 } else { return 金额不足; } } else { return 非VIP用户; } } else { return 用户未登录; }优化后的版本if (user null) return 用户未登录; if (!user.isVip()) return 非VIP用户; if (order.getAmount() 100) return 金额不足; // 核心业务逻辑优化点分析减少嵌套层级从3层降为0层提前处理异常情况主流程更清晰代码可读性提升300%实测2.2 Optional的妙用Java8的Optional不仅能处理null还能优雅地替代if/else// 传统写法 if (order ! null) { if (order.getUser() ! null) { if (order.getUser().getAddress() ! null) { return order.getUser().getAddress().getCity(); } } } return 未知城市; // Optional写法 return Optional.ofNullable(order) .map(Order::getUser) .map(User::getAddress) .map(Address::getCity) .orElse(未知城市);注意事项Optional不要滥用简单的null检查直接用if更直观3. 设计模式实战3.1 策略模式深度应用当遇到这种代码时就该考虑策略模式了if (paymentType.equals(alipay)) { // 支付宝支付逻辑 } else if (paymentType.equals(wechat)) { // 微信支付逻辑 } else if (paymentType.equals(unionpay)) { // 银联支付逻辑 } // 还有10多种支付方式...3.1.1 经典策略模式实现interface PaymentStrategy { void pay(BigDecimal amount); } class AlipayStrategy implements PaymentStrategy { Override void pay(BigDecimal amount) { // 支付宝具体实现 } } // 其他策略实现类... // 使用方式 PaymentStrategy strategy PaymentStrategyFactory.getStrategy(paymentType); strategy.pay(amount);3.1.2 枚举策略进阶版public enum PaymentStrategy { ALIPAY { Override public void pay(BigDecimal amount) { // 支付宝实现 } }, WECHAT { Override public void pay(BigDecimal amount) { // 微信实现 } }; public abstract void pay(BigDecimal amount); } // 使用方式 PaymentStrategy.valueOf(paymentType).pay(amount);实战经验枚举策略适合分支较少10个且稳定的场景否则还是用传统策略模式更易扩展3.2 表驱动法实战遇到这种代码时表驱动法是绝佳选择if (month 1) return 31; if (month 2) return 28; // ... 其他月份优化方案private static final int[] MONTH_DAYS { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; public int getDays(int month) { return MONTH_DAYS[month - 1]; }进阶版考虑闰年private static final int[][] MONTH_DAYS { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, // 平年 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // 闰年 }; public int getDays(int year, int month) { int isLeap (year % 4 0 year % 100 ! 0) || year % 400 0 ? 1 : 0; return MONTH_DAYS[isLeap][month - 1]; }4. 高级重构技巧4.1 状态模式解复杂条件当业务逻辑包含大量状态判断时if (order.getStatus().equals(UNPAID)) { if (paymentTime 0) { // 支付超时逻辑 } else { // 待支付逻辑 } } else if (order.getStatus().equals(PAID)) { if (shipTime null) { // 待发货逻辑 } else if (receiveTime null) { // 待收货逻辑 } } // 其他状态...使用状态模式重构interface OrderState { void handle(OrderContext context); } class UnpaidState implements OrderState { Override void handle(OrderContext context) { if (context.getPaymentTime() 0) { // 支付超时逻辑 } else { // 待支付逻辑 } } } // 使用方式 OrderState state OrderStateFactory.getState(order.getStatus()); state.handle(orderContext);4.2 责任链模式处理校验链多层if校验的典型场景if (StringUtils.isEmpty(username)) { return 用户名不能为空; } if (username.length() 6) { return 用户名至少6位; } if (!Pattern.matches([a-zA-Z0-9], username)) { return 用户名包含非法字符; } // 更多校验...使用责任链模式重构public interface Validator { String validate(String input); Validator setNext(Validator next); } public class EmptyValidator implements Validator { private Validator next; Override public String validate(String input) { if (StringUtils.isEmpty(input)) { return 用户名不能为空; } return next ! null ? next.validate(input) : null; } // 其他校验器实现... } // 构建校验链 Validator chain new EmptyValidator() .setNext(new LengthValidator()) .setNext(new PatternValidator()); // 使用方式 String error chain.validate(username);5. 重构实战经验5.1 重构步骤指南建立安全网确保有完善的单元测试覆盖小步前进每次只重构一小部分立即验证版本控制每完成一个重构阶段就提交一次性能评估重构后要进行性能对比测试文档更新同步更新相关技术文档5.2 常见坑点记录过度设计不是所有if/else都需要重构简单逻辑保持原样性能陷阱策略模式会带来对象创建开销高频调用处要注意线程安全共享的策略对象要注意并发问题调试困难多态会让调试变得复杂记得加好日志新人理解成本设计模式会增加代码抽象度要做好注释5.3 代码可读性平衡术完全消除if/else不是目的关键是要平衡可读性同事能否快速理解可维护性后续修改是否方便扩展性新增需求是否容易实现性能运行时开销是否可接受我个人的经验法则是超过3层的嵌套或者超过5个的if/else分支就考虑重构。但对于简单的条件判断保持原样反而更清晰。