基本概念
建造者模式指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。它使得各个建造者相互独立,有利于系统扩展,并且能够精细地控制对象创建过程,而客户端无需知道具体过程。
应用场景列举
1. 创建的对象比较复杂,由多个构件构成,构件多样化,但创建方式基本相同;
2. 创建对象构件的算法是独立的,比如创建建筑模型,每个模型创建过程都是一样的,梁板柱等构件对应各自的算法,且不同类结构类型创建也略有不同(使用不同建造者)。
实现
如上图,建造者模式必须有几个角色:抽象建造者(Builder)、若干个具体建造者(ConcreteBuilder)、指挥者(Director)和被建造的对象(Product),客户端通过指挥者创建对象。
@Data
public class Product {
private Part part1;
private Part part2;
private Part part3;
@Data
static class Part {
private String name;
public Part(String name) {
this.name = name;
}
}
}
/**
* 抽象建造者
*/
public abstract class Builder {
protected Product product = new Product();
public abstract void buildPart1();
public abstract void buildPart2();
public abstract void buildPart3();
public Product build() {
return product;
}
}
/**
* 建造者1
*/
public class ConcreteBuilder1 extends Builder {
@Override
public void buildPart1() {
product.setPart1(new Part("builder1创建part1"));
}
@Override
public void buildPart2() {
product.setPart2(new Part("builder1创建part2"));
}
@Override
public void buildPart3() {
product.setPart3(new Part("builder1创建part3"));
}
}
/**
* 建造者2
*/
public class ConcreteBuilder2 extends Builder {
@Override
public void buildPart1() {
product.setPart1(new Part("builder2创建part1"));
}
@Override
public void buildPart2() {
product.setPart2(new Part("builder2创建part2"));
}
@Override
public void buildPart3() {
product.setPart3(new Part("builder2创建part3"));
}
}
/**
* 指挥者
*/
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public Product build() {
builder.buildPart1();
builder.buildPart2();
builder.buildPart3();
return builder.build();
}
}
public class Test {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder1();
Director director = new Director(builder);
Product product = director.build();
System.out.println(product);
}
}
测试结果如下:
举例
模拟在智慧建筑系统中,创建一个三维建筑模型。
/**
* 建筑类
*/
@Data
public class Building {
private String id; // 建筑id
private String name; // 建筑名称
private String description; // 描述
private Column column; // 柱,需要建造者创建
private Beam beam; // 梁,需要建造者创建
private Plate plate; // 板,需要建造者创建
@Override
public String toString() {
return "Building{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", " + column +
", " + beam +
", " + plate +
'}';
}
}
/**
* 柱
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class Column extends BuildingComponent {
public Column(String id) {
setId(id);
}
protected int[] sectionSize; // 横截面尺寸
@Override
public String toString() {
return "Column【" + getId() + "】";
}
}
/**
* 梁
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class Beam extends BuildingComponent {
public Beam(String id) {
setId(id);
}
private int[] sectionSize; // 横截面尺寸
@Override
public String toString() {
return "Beam【" + getId() + "】";
}
}
/**
* 板
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class Plate extends BuildingComponent {
public Plate(String id) {
setId(id);
}
private int[] size; // 板面尺寸
private int height; // 板截面高度
@Override
public String toString() {
return "Plate【" + getId() + "】";
}
}
@Data
public class BuildingComponent {
private String id;
private int elevation; // 标高位置
private double[] center; // 中心位置
}
/**
* 建筑结构类型
*/
public enum BuildingStructureType {
STEEL,
FRAME,
SHEAR_WALL
}
/**
* 建筑模型建造者
*/
public abstract class BuildingBuilder {
protected Building building = new Building();
/**
* 建造柱
*/
public abstract void buildColumn();
/**
* 建造梁
*/
public abstract void buildBeam();
/**
* 建造板
*/
public abstract void buildPlate();
public Building build() {
return building;
}
}
/**
* 框架结构建造者
*/
public class FrameStructureBuilder extends BuildingBuilder {
@Override
public void buildColumn() {
building.setColumn(new Column("建造框架结构柱"));
}
@Override
public void buildBeam() {
building.setBeam(new Beam("建造框架结构梁"));
}
@Override
public void buildPlate() {
building.setPlate(new Plate("建造框架结构板"));
}
}
/**
* 剪力墙结构建造者
*/
public class ShearWallStructureBuilder extends BuildingBuilder {
@Override
public void buildColumn() {
building.setColumn(new Column("建造剪力墙结构柱"));
}
@Override
public void buildBeam() {
building.setBeam(new Beam("建造剪力墙结构梁"));
}
@Override
public void buildPlate() {
building.setPlate(new Plate("建造剪力墙结构板"));
}
}
/**
* 钢结构建造者
*/
public class SteelStructureBuilder extends BuildingBuilder {
@Override
public void buildColumn() {
building.setColumn(new Column("建造钢结构柱"));
}
@Override
public void buildBeam() {
building.setBeam(new Beam("建造钢结构梁"));
}
@Override
public void buildPlate() {
building.setPlate(new Plate("建造钢结构板"));
}
}
/**
* 建造者工厂
*/
public class BuildingBuilderFactory {
public static BuildingBuilder createBuildingBuilder(BuildingStructureType type) {
BuildingBuilder builder;
switch (type) {
case FRAME:
builder = new FrameStructureBuilder();
break;
case STEEL:
builder = new SteelStructureBuilder();
break;
case SHEAR_WALL:
builder = new ShearWallStructureBuilder();
break;
default:
builder = null;
break;
}
return builder;
}
}
/**
* 指挥者
*/
public class BuildingDirector {
private BuildingBuilder buildingBuilder;
public BuildingDirector(BuildingBuilder buildingBuilder) {
this.buildingBuilder = buildingBuilder;
}
public Building build() {
buildingBuilder.buildColumn(); // 建造柱
buildingBuilder.buildBeam(); // 建造梁
buildingBuilder.buildPlate(); // 建造板
return buildingBuilder.build(); // 创建建筑对象
}
}
public class Test {
public static void main(String[] args) {
BuildingBuilder builder = BuildingBuilderFactory.createBuildingBuilder(BuildingStructureType.SHEAR_WALL);
BuildingDirector director = new BuildingDirector(builder);
Building building = director.build();
building.setId("building001");
building.setName("华为智慧园区三期主楼");
System.out.println(building.toString());
builder = BuildingBuilderFactory.createBuildingBuilder(BuildingStructureType.FRAME);
director = new BuildingDirector(builder);
building = director.build();
building.setId("building002");
building.setName("华为智慧园区三期裙楼");
System.out.println(building);
}
}
测试结果如下: