Java实现Builder模式如何适配单元测试无需引用外部类的要求
适配单元测试的Builder模式调整方案
问题根源
你当前将CarFactory设为Car的静态内部类,虽然静态内部类不需要依赖外部类实例即可实例化,但语法要求必须通过Car.CarFactory的形式引用,和单元测试直接new CarFactory()的调用规则不兼容。
最优解决方案:将CarFactory调整为独立顶级类
该方案改动最小,完全符合单元测试调用要求,同时不破坏原有封装性:
- 把
CarFactory从Car的内部类定义中剥离,作为同包下的独立public类 - 将
Car的构造器设置为包级私有(去掉private修饰符),保证只有同包的CarFactory可以实例化Car,避免外部随意创建Car实例
代码示例
原错误实现(需调整)
public class Car { private int maxSpeed; // 其他属性省略 private Car() {} // 静态内部类,调用需要加Car.前缀 public static class CarFactory { // 链式配置方法 public CarFactory engine(String level) { /* 逻辑省略 */ return this; } public CarFactory tire(String level) { /* 逻辑省略 */ return this; } public CarFactory chassis(String level) { /* 逻辑省略 */ return this; } public Car build() { /* 造车主逻辑 */ } } }
调整后实现
// Car.java 与CarFactory同包 public class Car { // 四项属性 private int maxSpeed; private int acceleration; private int maneuverability; private int brakeDistance; // 包级私有构造器,仅同包类可访问 Car() {} // 按需添加属性getter,满足单元测试校验需求 public int getMaxSpeed() { return maxSpeed; } public int getAcceleration() { return acceleration; } public int getManeuverability() { return maneuverability; } public int getBrakeDistance() { return brakeDistance; } }
// CarFactory.java 与Car同包 public class CarFactory { private String engineLevel; private String tireLevel; private String chassisLevel; // 链式配置方法,保持原有调用逻辑 public CarFactory engine(String level) { this.engineLevel = level; return this; } public CarFactory tire(String level) { this.tireLevel = level; return this; } public CarFactory chassis(String level) { this.chassisLevel = level; return this; } public Car build() { Car car = new Car(); // 按规则计算四项属性赋值 car.maxSpeed = calculateMaxSpeed(engineLevel, chassisLevel); car.acceleration = calculateAcceleration(engineLevel, tireLevel); car.maneuverability = calculateManeuverability(tireLevel, chassisLevel); car.brakeDistance = calculateBrakeDistance(tireLevel, chassisLevel); return car; } // 内部属性计算方法,按需实现即可 private int calculateMaxSpeed(String engine, String chassis) { /* 实现逻辑 */ } private int calculateAcceleration(String engine, String tire) { /* 实现逻辑 */ } private int calculateManeuverability(String tire, String chassis) { /* 实现逻辑 */ } private int calculateBrakeDistance(String tire, String chassis) { /* 实现逻辑 */ } }
调整后可直接通过new CarFactory()实例化,链式配置、build生成Car的逻辑完全不变,完美适配单元测试要求。
妥协适配方案(不改动原有内部类结构)
如果必须保留Car.CarFactory的内部类结构,可以新增一个同包下的空继承类做适配:
// CarFactory.java 同包下新增 public class CarFactory extends Car.CarFactory { // 无需额外实现,自动继承父类所有方法 }
该方案不需要改动原有内部类代码,但会多出冗余类,优先推荐第一种方案。
内容的提问来源于stack exchange,提问作者UlrichGiorgioJaeger
相关产品推荐
相关产品推荐

