建造者模式:指挥者能否直接接收具体建造者类型?
问题
在学习建造者设计模式时产生了疑问:为何指挥者不能接收具体建造者类型的引用?假设存在一个CarBuilder接口,由SUVCarBuilder和SportsCarBuilder两个具体建造者实现。常规的指挥者类方法接收Builder类型而非具体建造者类型,那指挥者是否可以直接接收具体建造者类型,进而直接返回具体产品?
以下为两种指挥者类的实现代码示例:
常规实现方式
public class Director { public void constructSportsCar(Builder builder) { builder.setCarType(CarType.SPORTS_CAR); builder.setSeats(2); builder.setEngine(new Engine(3.0, 0)); builder.setTransmission(Transmission.SEMI_AUTOMATIC); builder.setTripComputer(new TripComputer()); builder.setGPSNavigator(new GPSNavigator()); } public void constructSUV(Builder builder) { builder.setCarType(CarType.SUV); builder.setSeats(4); builder.setEngine(new Engine(2.5, 0)); builder.setTransmission(Transmission.MANUAL); builder.setGPSNavigator(new GPSNavigator()); } }
接收具体建造者的实现方式
public class Director { public SportsCar constructSportsCar(SportsCarBuilder builder) { builder.setCarType(CarType.SPORTS_CAR); builder.setSeats(2); builder.setEngine(new Engine(3.0, 0)); builder.setTransmission(Transmission.SEMI_AUTOMATIC); builder.setTripComputer(new TripComputer()); builder.setGPSNavigator(new GPSNavigator()); // Get the concrete product return builder.getSportsCar(); } public SUVCar constructSUV(SUVCarBuilder builder) { builder.setCarType(CarType.SUV); builder.setSeats(4); builder.setEngine(new Engine(2.5, 0)); builder.setTransmission(Transmission.MANUAL); builder.setGPSNavigator(new GPSNavigator()); // Get the concrete product return builder.getSUVCar(); } }
分析与解答
1. 常规方式的核心优势:守好开闭与解耦的底线
指挥者接收抽象Builder类型,核心是遵循依赖倒置原则——高层模块(指挥者)只依赖抽象接口,不盯具体实现。这么做的好处很实在:
- 以后加新的建造者(比如
TruckBuilder),根本不用改指挥者的代码,只要新类实现CarBuilder接口,直接就能用现有构造方法,完全符合开闭原则,不用反复折腾老代码。 - 指挥者只管定义“怎么拼出产品”的流程,不管具体用哪个建造者、拼出来的产品细节是什么,和具体实现彻底解耦,后续维护起来省心太多。
2. 直接用具体建造者的坑
第二种方式虽然能直接返回具体产品,但问题不小:
- 违反开闭原则:每加一种新的具体建造者,就得在指挥者里加对应的新方法,指挥者的代码会越写越臃肿,后期新增产品时改起来头疼。
- 耦合太死:指挥者直接绑定具体建造者和具体产品,比如哪天
SportsCarBuilder把getSportsCar()改成buildSportsCar(),指挥者的代码必须跟着改,牵一发而动全身。 - 浪费建造者模式的价值:建造者模式本来就是要把“造产品的流程”和“具体怎么造”分开,第二种方式把两者绑死,等于白用了这个模式的核心优势。
3. 特殊场景下的妥协?
如果你的业务完全固定,确定不会加新的产品类型,而且需要直接拿到具体产品类型、不想做类型转换,第二种方式也能凑合用,但这属于特殊场景下的权宜之计,不是建造者模式的常规用法。
内容的提问来源于stack exchange,提问作者Number945
相关产品推荐
相关产品推荐

