建造者模式(Builder Pattern),通常用于创建一个复杂对象,其构建过程允许对象的表示与其构造过程分离。这种模式的主要目的是将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
1.主要组成
-
Director(指挥者): 负责使用构建者接口,以一定的顺序构建一个复杂对象。它不关心具体的构建过程,只关心构建的顺序和构建的步骤。
-
Builder(抽象建造者): 定义了创建一个产品的各个部件的抽象接口。具体的建造者将实现这个接口,以构建和装配各个部件。
-
ConcreteBuilder(具体建造者): 实现了Builder接口,负责构建和装配产品的各个部件。它具体了解构建的细节,并负责处理构建过程中的逻辑。
-
Product(产品): 被构建的复杂对象。它包含了被构建对象的各个部件。
2.主要步骤
-
定义产品的部件和产品的接口: 确定要构建的复杂对象的结构,并定义产品接口。
-
创建具体的建造者类: 实现抽象建造者接口,负责构建和装配产品的各个部件。
-
创建指挥者类: 负责使用建造者接口,按照一定的顺序组织和调用具体建造者类的方法,从而构建产品。
-
使用建造者模式: 客户端通过指挥者调用具体建造者的方法,从而构建产品。客户端无需关心产品的具体构建过程。
3.优点
-
分离构建过程和表示: 建造者模式允许你分离一个复杂对象的构建过程和最终的表示,使得相同的构建过程可以创建不同的表示。
-
更好的控制复杂对象的构建: 具体的建造者类负责复杂对象的构建过程,从而更容易控制对象的构建。
-
更好的复用性: 可以通过不同的具体建造者类创建不同的产品,提高了复用性。
-
客户端无需关心产品的构建过程: 客户端只需选择合适的建造者和使用指挥者来构建产品,无需关心产品的具体构建过程。
4.缺点
-
增加了代码复杂性: 引入了多个具体建造者类、指挥者类等,可能导致代码结构变得更加复杂。
-
适用范围有限: 建造者模式主要适用于构建复杂对象的情况,如果对象比较简单,使用建造者模式可能显得过于繁琐。
-
不容易适应变化: 如果产品的构建过程相对稳定,很少发生变化,使用建造者模式可能会显得过度设计。
5.适用场景
建造者模式通常在以下情况下比较适用:
-
构建一个复杂对象的算法,应该独立于该对象的组成部分以及它们的装配方式时。
-
构建过程必须允许构建不同表示的对象时。
-
客户端不需要知道产品的具体构建过程,只需知道如何使用产品时。
6.实例
首先,定义产品的接口,即汽车类:
// Product: 汽车类
class Car {
private String engine;
private String tire;
private String color;
public void setEngine(String engine) {
this.engine = engine;
}
public void setTire(String tire) {
this.tire = tire;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Car{" +
"engine='" + engine + '\'' +
", tire='" + tire + '\'' +
", color='" + color + '\'' +
'}';
}
}
接下来,定义抽象建造者接口,即汽车建造者接口:
// Builder: 汽车建造者接口
interface CarBuilder {
void buildEngine();
void buildTire();
void buildColor();
Car getResult();
}
然后,创建具体的建造者类,例如豪华版和经济版的汽车建造者:
// ConcreteBuilder: 豪华版汽车建造者
class LuxuryCarBuilder implements CarBuilder {
private Car car = new Car();
@Override
public void buildEngine() {
car.setEngine("豪华发动机");
}
@Override
public void buildTire() {
car.setTire("豪华轮胎");
}
@Override
public void buildColor() {
car.setColor("土豪金");
}
@Override
public Car getResult() {
return car;
}
}
// ConcreteBuilder: 经济版汽车建造者
class EconomyCarBuilder implements CarBuilder {
private Car car = new Car();
@Override
public void buildEngine() {
car.setEngine("普通引擎");
}
@Override
public void buildTire() {
car.setTire("普通轮胎");
}
@Override
public void buildColor() {
car.setColor("白色");
}
@Override
public Car getResult() {
return car;
}
}
接着,定义指挥者类,此处以汽车销售员为例:
// Director: 汽车销售员
class CarSalesman {
private CarBuilder carBuilder;
public CarSalesman(CarBuilder carBuilder) {
this.carBuilder = carBuilder;
}
public void constructCar() {
carBuilder.buildEngine();
carBuilder.buildTire();
carBuilder.buildColor();
}
public Car getCar() {
return carBuilder.getResult();
}
}
最后,我们可以使用建造者模式构建不同配置的汽车:
public class BuilderPatternCarExample {
public static void main(String[] args) {
// 创建豪华版汽车
CarBuilder luxuryCarBuilder = new LuxuryCarBuilder();
CarSalesman luxuryCarSalesman = new CarSalesman(luxuryCarBuilder);
luxuryCarSalesman.constructCar();
Car luxuryCar = luxuryCarSalesman.getCar();
System.out.println("豪华汽车: " + luxuryCar);
// 创建经济版汽车
CarBuilder economyCarBuilder = new EconomyCarBuilder();
CarSalesman economyCarSalesman = new CarSalesman(economyCarBuilder);
economyCarSalesman.constructCar();
Car economyCar = economyCarSalesman.getCar();
System.out.println("经济型汽车: " + economyCar);
}
}
在这个例子中,我们通过建造者模式实现了构建不同配置汽车的过程,客户端只需关心选择合适的建造者和使用销售员来构建汽车。这种方式使得产品的构建过程与其表示相分离,同时也提供了更好的控制和灵活性。