目录
- 1. 简介
- 2. 代码
- 2.1 Car
- 2.2 Builder
- 2.3 CarBuilder
- 2.4 Engineer
- 2.5 Test
- 3. 总结
1. 简介
建造者模式(Builder Pattern)是一种创建型设计模式。它将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。简单来说,就是把对象的创建和对象的组装分开,这样可以更灵活地创建对象。
当我们需要创建一个复杂对象时,这个对象可能有很多属性,而且这些属性的设置顺序和组合方式可能有多种情况。如果直接在一个构造函数或者工厂方法中设置所有属性,代码会变得很复杂且难以维护。建造者模式通过将复杂对象的构建过程分解为多个步骤,由一个指挥者(Director
)来控制这些步骤的执行顺序,而具体的构建步骤则由建造者(Builder
)来实现。
结构组成:
- 产品(
Product
)
这是我们最终要创建的复杂对象。例如,在建造房屋的场景中,房屋就是产品。它可能包含多个部件,如房间、门窗、屋顶等。产品类通常有多个属性来表示其各个组成部分。 - 抽象建造者(
Builder
)
它定义了创建产品各个部件的抽象方法。这些方法规定了如何构建产品的各个部分。例如,抽象的房屋建造者可能有创建房间、创建门窗、安装屋顶等抽象方法 - 具体建造者(
Concrete Builder
)
它实现了抽象建造者的抽象方法,具体定义了如何构建产品的各个部分。不同的具体建造者可以按照不同的方式构建产品。比如,有一个豪华房屋建造者和一个普通房屋建造者,它们对房间数量、门窗质量、屋顶材料等的构建方式可能不同。 - 指挥者(
Director
)
指挥者负责控制建造过程,它知道如何正确地调用建造者的方法来构建产品。它通过调用建造者的方法来规定构建产品的步骤和顺序。例如,指挥者可以规定先建造房间,再安装门窗,最后安装屋顶。
2. 代码
2.1 Car
java">package yxz.builder;public class Car {private String basePlate;private String frame;private String door;@Overridepublic String toString() {return "Car{" +"basePlate='" + basePlate + '\'' +", frame='" + frame + '\'' +", door='" + door + '\'' +'}';}public String getBasePlate() {return basePlate;}public void setBasePlate(String basePlate) {this.basePlate = basePlate;}public String getFrame() {return frame;}public void setFrame(String frame) {this.frame = frame;}public String getDoor() {return door;}public void setDoor(String door) {this.door = door;}
}
2.2 Builder
java">package yxz.builder;public abstract class Builder {public abstract void buildBasePlate(String basePlste);public abstract void buildFrame(String frame);public abstract void buildDoor(String door);public abstract Car makeCar();
}
2.3 CarBuilder
java">package yxz.builder;public class CarBuilder extends Builder{private Car car = new Car();@Overridepublic void buildBasePlate(String basePlste) {car.setBasePlate(basePlste);}@Overridepublic void buildFrame(String frame) {car.setFrame(frame);}@Overridepublic void buildDoor(String door) {car.setDoor(door);}@Overridepublic Car makeCar() {return car;}
}
2.4 Engineer
java">package yxz.builder;public class Engineer {private CarBuilder carBuilder;public void setCarBuilder(CarBuilder carBuilder) {this.carBuilder = carBuilder;}public Car makeCar(String basePlate, String door, String frame){carBuilder.buildBasePlate(basePlate);carBuilder.buildDoor(door);carBuilder.buildFrame(frame);return carBuilder.makeCar();}
}
2.5 Test
java">package yxz.builder;public class Test {public static void main(String[] args) {CarBuilder carBuilder = new CarBuilder();// 创建工程师Engineer engineer = new Engineer();engineer.setCarBuilder(carBuilder);Car car = engineer.makeCar("制作车底盘","制作车门","制作车架");System.out.println(car);}
}
运行结果:
java">Car{basePlate='制作车底盘', frame='制作车架', door='制作车门'}
3. 总结
使用场景:
- 复杂对象的创建
当要创建的对象具有复杂的内部结构,并且其属性之间存在一定的依赖关系或者构建顺序要求时,适合使用建造者模式。例如,在创建一个汽车对象时,汽车有车身、发动机、轮胎等多个部件,而且这些部件的安装顺序很重要,并且不同类型的汽车(如轿车、SUV)在部件的具体构造上有所不同,就可以使用建造者模式。 - 对象构建过程的复用
如果有多个类似的对象需要创建,它们的构建过程大部分相同,只有部分细节不同,那么可以通过建造者模式复用构建过程。比如,在游戏开发中,要创建多种不同类型的怪物,怪物都有身体、武器、技能等部分,构建过程类似,但具体的身体形态、武器类型、技能效果等有所不同。可以定义一个怪物建造者,通过不同的具体建造者来创建不同的怪物,而构建过程(如先创建身体,再添加武器,最后赋予技能)可以在指挥者中复用。
优缺点:
- 优点
- 可扩展性强:可以很容易地通过增加新的具体建造者来创建新类型的产品。例如,如果要创建一种新型的房屋,只需要增加一个新的房屋建造者类,实现相应的构建方法即可。
- 构建过程的复用:指挥者可以复用构建过程,使得相同的构建步骤可以用于创建不同的产品。这在需要批量创建相似对象时非常高效。
- 封装性好:产品的构建过程封装在建造者和指挥者中,对于客户端代码来说,只需要关心最终产品的获取,不需要了解复杂的构建过程。
- 缺点
- 代码复杂度增加:由于引入了多个类(抽象建造者、具体建造者、指挥者等),会导致代码结构相对复杂,对于简单的对象创建场景可能会显得有些 “大材小用”。
- 需要额外的代码维护成本:增加的类和它们之间的关系需要更多的代码来维护,特别是当产品的结构或者构建过程发生变化时,可能需要修改多个类的代码。