手撕设计模式——复杂对象之生成器模式
1.业务需求
大家好,我是菠菜啊,好久不见,今天给大家带来的是创建型模式——生成器模式。老规矩,在介绍这期生成器模式前,我们先来看看这样的需求:现在有一个汽车装配的流水线,要支持轮胎、座椅、发动机等配件客户的定制,我们该怎么设计?

2.代码实现
Talk is cheap,show me your code.
实现初步思路:
上一章我们学习了工厂方法模式,我们首先会想到用工厂模式实现。但是仔细一想,工厂是侧重一系列对象创建的方式,而上述需求是注重对象内部的创建细节、组成部分、创建步骤等。这样显然不合适,所以初级版本如下。
初始版本:
public class Car {
//发动机
private Engine engine;
//轮胎
private Tyre tyre;
//座椅
private Chair chair;
public void setEngine(Engine engine) {
this.engine = engine;
}
public void setTyre(Tyre tyre) {
this.tyre = tyre;
}
public void setChair(Chair chair) {
this.chair = chair;
}
public Engine getEngine() {
return engine;
}
public Tyre getTyre() {
return tyre;
}
public Chair getChair() {
return chair;
}
public Car() {
}
public Car(Engine engine, Tyre tyre, Chair chair) {
this.engine = engine;
this.tyre = tyre;
this.chair = chair;
}
public void showCar() {
System.out.println(this);
}
@Override
public String toString() {
return "Car{" +
"engine=" + engine +
", tyre=" + tyre +
", chair=" + chair +
'}';
}
}
//发动机
public class Engine {
//品牌
private String brand;
//型号
private String model;
//排量
private double displacement;
public Engine(String brand, String model, double displacement) {
this.brand = brand;
this.model = model;
this.displacement = displacement;
}
@Override
public String toString() {
return "Engine{" +
"brand='" + brand + ''' +
", model='" + model + ''' +
", displacement=" + displacement +
'}';
}
}
//轮胎
public class Tyre {
//品牌
private String brand;
//型号
private String model;
//尺寸
private int size;
public Tyre(String brand, String model, int size) {
this.brand = brand;
this.model = model;
this.size = size;
}
@Override
public String toString() {
return "Tyre{" +
"brand='" + brand + ''' +
", model='" + model + ''' +
", size=" + size +
'}';
}
}
//座椅
public class Chair {
//品牌
private String brand;
//型号
private String model;
//配置
private String configure;
public Chair(String brand, String model, String configure) {
this.brand = brand;
this.model = model;
this.configure = configure;
}
@Override
public String toString() {
return "Chair{" +
"brand='" + brand + ''' +
", model='" + model + ''' +
", configure='" + configure + ''' +
'}';
}
}
//客户端
public class Client {
public static void main(String[] args) {
Car car1=new Car(new Engine("Benz","E200",2.5),new Tyre("韩泰","T200",18),new Chair("奔驰","C200","高配"));
car1.showCar();
System.out.println("------------------------------------------------------------------------");
Car car2=new Car(new Engine("宝马","325Li",3.5),new Tyre("米其林","T300",19),new Chair("宝马","325","低配"));
car2.showCar();
}
}
实现代码结构图:

思考:上述代码会发现,汽车对象的创建和表示没有分离,建造一辆汽车太复杂了,有上百种配件,如果要这么制造客户端知道的细节太多了,代码的耦合性太强了,并且生产组装一辆汽车的步骤和配件基本上一样的,可以抽象出来,于是有了以下升级方案。
3.方案改进
实现代码结构图:

汽车主管类:
public class CarDirector {
private CarBuilder carBuilder;
public CarDirector(CarBuilder carBuilder) {
this.carBuilder = carBuilder;
}
public Car build() {
carBuilder.buildChair();
carBuilder.buildEngine();
carBuilder.buildTyre();
return carBuilder.getCar();
}
}
汽车生成器抽象类:
public abstract class CarBuilder {
protected Car car=new Car();
public abstract void buildEngine();
public abstract void buildTyre();
public abstract void buildChair();
public Car getCar(){
return car;
}
}
奥迪汽车生成器类:
public class AudiConcreteCarBuilder extends CarBuilder {
@Override
public void buildEngine() {
car.setEngine(new Engine("奥迪","A4L",2.0));
}
@Override
public void buildTyre() {
if(car.getEngine()== null){
throw new RuntimeException("必须先安装发动机");
}
car.setTyre(new Tyre("朝阳","T300",17));
}
@Override
public void buildChair() {
if(car.getEngine()== null){
throw new RuntimeException("必须先安装发动机");
}
if(car.getTyre()== null){
throw new RuntimeException("必须先安装轮胎");
}
car.setChair(new Chair("奥迪","A4L","低配"));
}
}
奔驰汽车生成器类:
public class BenzConcreteCarBuilder extends CarBuilder {
@Override
public void buildEngine() {
car.setEngine(new Engine("奔驰","E200",2.5));
}
@Override
public void buildTyre() {
if(car.getEngine()== null){
throw new RuntimeException("必须先安装发动机");
}
car.setTyre(new Tyre("韩泰","T200",18));
}
@Override
public void buildChair() {
if(car.getEngine()== null){
throw new RuntimeException("必须先安装发动机");
}
if(car.getTyre()== null){
throw new RuntimeException("必须先安装轮胎");
}
car.setChair(new Chair("奔驰","C200","高配"));
}
}
宝马汽车生成器类:
public class BMWConcreteCarBuilder extends CarBuilder {
@Override
public void buildEngine() {
car.setEngine(new Engine("宝马","325Li",2.0));
}
@Override
public void buildTyre() {
if(car.getEngine()== null){
throw new RuntimeException("必须先安装发动机");
}
car.setTyre(new Tyre("powertec","T300",17));
}
@Override
public void buildChair() {
if(car.getEngine()== null){
throw new RuntimeException("必须先安装发动机");
}
if(car.getTyre()== null){
throw new RuntimeException("必须先安装轮胎");
}
car.setChair(new Chair("宝马","325","低配"));
}
}
client类:
public class Client2 {
public static void main(String[] args) {
CarDirector carDirector1=new CarDirector(new BMWConcreteCarBuilder());
Car car1=carDirector1.build();
car1.showCar();
System.out.println("------------------------------------------------------------------------");
CarDirector carDirector2=new CarDirector(new BenzConcreteCarBuilder());
Car car2=carDirector2.build();
car2.showCar();
System.out.println("------------------------------------------------------------------------");
CarDirector carDirector3=new CarDirector(new AudiConcreteCarBuilder());
Car car3=carDirector3.build();
car3.showCar();
}
}
思考:如果安装上述代码的实现,如果要组装一辆车,只需要告诉汽车主管组装什么类型的车(也就是指定具体的生成器)就行了,使用者不需要知道建造的全部细节,这种设计模式叫做——生成器模式,又叫建造者模式(Builder Pattern)。
4.定义和组成结构
建造者模式(Builder Pattern)指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

主要角色:
- 产品(Product):具体生成器要构造的复杂对象;
- 抽象生成器(Builder):抽象生成器是一个接口,该接口除了为创建一个Product对象的各个组件定义了若干个方法外,还要定义返回Product对象的方法
- 具体生成器(ConcreteBuilder):实现了Builder接口的类,具体生成器将实现Builder接口所定义的方法。;
- 指挥者(Director):指挥者是一个类,该类需含有Builder接口声明的变量。指挥者的职责是负责向用户提供具体生成器,即指挥者将请求具体生成器来构造用户所需要的Product对象,如果所请求的具体对象生成器成功德构造出Product对象,指挥者就可以让该具体生成器返回所构造的Product对象。
5.优缺点以及应用场景
优点:
- 产品使用者和创建者解耦,无须知道产品的内部的组成细节,对象的构建过程与表示分离(使用相同的构建过程来创建不同的表示)
- 扩展性好,各个具体的创建者相互独立,满足单一原则和开闭原则
缺点:
- 产品对象的组成部分或创建步骤必须相同
- 产品的内部发生变化,建造者也要同步修改,维护成本高
- 引入了多个抽象和具体类,增加了系统的复杂度和理解难度
适用场景:
- 对象创建复杂、多步骤创建
- 根据不同需求创建内部细节不同对象
现实应用场景:
-
StringBuilder和StringBuffer:这俩个类都提供了动态生成字符串的构建功能,高效地创建和拼接字符串。
-
数据库查询构造器:如 MyBatis 中的
SqlBuilder、Hibernate 的CriteriaBuilder,都使用了建造者模式来构建复杂的查询语句。
6.和工厂模式对比
-
关注点不同:工厂模式关注的是对象的创建,建造者模式关注的是对象的构造过程。
-
复杂度不同:工厂模式通常用于创建单个对象,建造者模式用于创建具有复杂结构的对象。
-
使用场景不同:工厂模式适用于当创建逻辑简单且对象创建后直接可用的情况,建造者模式适用于需要一步步构建复杂对象的情况。
技术需要沉淀,同样生活也是~
个人链接:博客,欢迎一起交流












Interesting take on bankroll management! Seeing platforms like jiligames ph legit prioritize secure deposits & fast verification (KYC) is crucial for player trust, especially with mobile gaming growing. Good article!
Excellent explanation of the Builder pattern! The car assembly analogy perfectly illustrates how separating construction from representation creates more flexible code. Just as customizing each component matters in complex object creation, attention to detail in features like the Super Ace Jili game’s multipliers and wild symbols makes for engaging user experiences. Great tutorial series!