重构遗留代码中的IF...ELSE逻辑:寻找Vehicle子类实例化的更优设计方案
完全同意你的看法!这种冗长的if-else链不仅每次新增车型都要修改原有代码(违反开闭原则),而且逻辑越堆越臃肿,后期维护起来简直是噩梦。下面给你几个实用的重构方案,都是业界常用的,你可以根据场景选择:
方案1:注册式工厂(最推荐的轻量方案)
这是我平时用得最多的方案,核心思路是用一个Map来存储「参数标识」和「对应的Vehicle子类构造器/创建逻辑」,把分散的创建逻辑集中管理,新增车型时完全不用修改原有工厂代码。
示例代码:
import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; public class VehicleFactory { // 用Supplier来封装创建逻辑,支持无参构造 private static final Map<String, Supplier<Vehicle>> VEHICLE_CREATORS = new HashMap<>(); // 静态初始化块注册所有现有车型 static { VEHICLE_CREATORS.put("car", Car::new); VEHICLE_CREATORS.put("bus", Bus::new); VEHICLE_CREATORS.put("motorcycle", Motorcycle::new); } // 对外提供的创建方法 public static Vehicle createVehicle(String param) { Supplier<Vehicle> creator = VEHICLE_CREATORS.get(param); if (creator == null) { throw new IllegalArgumentException("Unknown vehicle type: " + param); } return creator.get(); } // 可选:动态注册方法,支持运行时新增车型 public static void registerVehicle(String type, Supplier<Vehicle> creator) { VEHICLE_CREATORS.put(type, creator); } }
使用的时候只需要一行:
Vehicle vehicle = VehicleFactory.createVehicle(param);
优点:
- 完全符合开闭原则,新增车型只需要调用
registerVehicle或者在静态块里加一行注册代码 - 代码简洁,逻辑集中,易维护
- 支持动态注册(比如从配置文件加载车型)
如果你的项目用了Spring,还可以通过依赖注入自动扫描所有Vehicle子类,把它们的构造器自动注册到Map里,连手动写静态块都省了。
方案2:简单工厂模式(基础优化版)
如果你的车型创建逻辑都很简单,而且短期内不会频繁新增车型,可以先用这个方案过渡,把分散的if-else集中到一个工厂类里,比原来的代码整洁很多。
示例代码:
public class SimpleVehicleFactory { public static Vehicle createVehicle(String param) { switch(param) { case "car": return new Car(); case "bus": return new Bus(); case "motorcycle": return new Motorcycle(); default: throw new IllegalArgumentException("Unknown vehicle type: " + param); } } }
注意:这个方案还是违反开闭原则,新增车型需要修改createVehicle方法,但比原来散落在业务代码里的if-else要好维护得多,至少所有创建逻辑都集中在一个地方。
方案3:工厂方法模式(复杂场景适配)
如果不同车型的创建逻辑比较复杂(比如需要初始化特定参数、依赖其他服务、加载配置文件等),可以用工厂方法模式,给每个车型单独创建一个工厂类,每个工厂负责自己的创建逻辑,符合单一职责原则。
示例代码:
// 抽象工厂接口 public interface VehicleFactory { Vehicle create(); } // Car的具体工厂 public class CarFactory implements VehicleFactory { @Override public Vehicle create() { // 这里可以加复杂的初始化逻辑,比如注入依赖、读取配置 Car car = new Car(); car.setMaxSpeed(200); return car; } } // Bus的具体工厂 public class BusFactory implements VehicleFactory { @Override public Vehicle create() { Bus bus = new Bus(); bus.setPassengerCapacity(50); return bus; } } // 工厂管理器,负责根据参数获取对应工厂 public class VehicleFactoryManager { private static final Map<String, VehicleFactory> FACTORIES = new HashMap<>(); static { FACTORIES.put("car", new CarFactory()); FACTORIES.put("bus", new BusFactory()); FACTORIES.put("motorcycle", new MotorcycleFactory()); } public static Vehicle createVehicle(String param) { VehicleFactory factory = FACTORIES.get(param); if (factory == null) { throw new IllegalArgumentException("Unknown vehicle type: " + param); } return factory.create(); } }
优点:
- 每个车型的创建逻辑独立,代码更清晰
- 新增车型只需要新增对应的工厂类和注册,不修改原有代码
- 适合创建逻辑复杂的场景
额外小建议
- 尽量避免字符串硬编码:可以定义一个
VehicleType枚举,把"car"、"bus"这些字符串封装成枚举常量,减少拼写错误 - 处理未知参数:一定要加默认分支抛出异常或者返回默认实现,避免NullPointerException
内容的提问来源于stack exchange,提问作者AllmanTool
相关产品推荐
相关产品推荐

