You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

建造者模式:指挥者能否直接接收具体建造者类型?

问题

在学习建造者设计模式时产生了疑问:为何指挥者不能接收具体建造者类型的引用?假设存在一个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 15:32:40