👉文章示例代码👈
定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
用户只需指定需要建造的类型就可以得到它们,建造过程及细节不需要知道。
建造者模式注重于方法的调用顺序,而工厂模式注重于创建产品。
四要素
标准建造者模式有四个要素:
- 产品类:既可以是具体的实体类,也可以是抽象类与其具体实现组成。
- 抽象建造者:接口或者抽象类,将具体的实现过程移交给子类。
- 具体建造者:抽象建造者的具体实现类,用于构建产品。
- 指挥者类:调用合适的建造者方法来构建产品。
场景示例
笔者这里以攒电脑为例。攒机需要购买一些配置,例如:CPU、主板、内存条、硬盘、显卡、机箱、电源、显示器等。然后按照自己的需求和喜好将这些配置攒起来组装成电脑,满足自己的个性化需求。当然也会有一些攒机的商家,来帮用户处理攒机的过程。
创建产品类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
public class Computer {
private String cpu;
private String mainboard;
private String memory;
private String hardDisk;
private String gpu;
private String crate;
private String powerSupply;
private String monitor;
@Override public String toString() { return "Computer{" + "cpu='" + cpu + '\'' + ", mainboard='" + mainboard + '\'' + ", memory='" + memory + '\'' + ", hardDisk='" + hardDisk + '\'' + ", gpu='" + gpu + '\'' + ", crate='" + crate + '\'' + ", powerSupply='" + powerSupply + '\'' + ", monitor='" + monitor + '\'' + '}'; } }
|
创建抽象建造者
抽象电脑建造者类中,额外提供一个组装电脑的方法,其返回参数为产品类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public abstract class ComputerBuilder {
public abstract void buyCpu(String cpu); public abstract void buyMainboard(String mainboard); public abstract void buyMemory(String memory); public abstract void buyHardDisk(String hardDisk); public abstract void buyGpu(String gpu); public abstract void buyCrate(String crate); public abstract void buyPowerSupply(String powerSupply); public abstract void buyMonitor(String monitor);
public abstract Computer assembleComputer(); }
|
创建具体建造者
创建具体的建造者类,继承我们的抽象创建者,实现抽象方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
public class ComputerActualBuilder extends ComputerBuilder {
private Computer computer = new Computer();
@Override public void buyCpu(String cpu) { computer.setCpu(cpu); }
@Override public void buyMainboard(String mainboard) { computer.setMainboard(mainboard); }
@Override public void buyMemory(String memory) { computer.setMemory(memory); }
@Override public void buyHardDisk(String hardDisk) { computer.setHardDisk(hardDisk); }
@Override public void buyGpu(String gpu) { computer.setGpu(gpu); }
@Override public void buyCrate(String crate) { computer.setCrate(crate); }
@Override public void buyPowerSupply(String powerSupply) { computer.setPowerSupply(powerSupply); }
@Override public void buyMonitor(String monitor) { computer.setMonitor(monitor); }
@Override public Computer assembleComputer() { return computer; } }
|
创建指挥者类
攒机商家是我们的指挥者,商家推荐配置供用户购买参考,帮助用户进行组装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
public class Enterprise {
private ComputerBuilder computerBuilder;
public void setComputerBuilder(ComputerBuilder computerBuilder) { this.computerBuilder = computerBuilder; }
public Computer assembleComputer(String cpu, String mainboard, String memory, String hardDisk, String gpu, String crate, String powerSupply, String monitor) { computerBuilder.buyCpu(cpu); computerBuilder.buyMainboard(mainboard); computerBuilder.buyMemory(memory); computerBuilder.buyHardDisk(hardDisk); computerBuilder.buyGpu(gpu); computerBuilder.buyCrate(crate); computerBuilder.buyPowerSupply(powerSupply); computerBuilder.buyMonitor(monitor);
return computerBuilder.assembleComputer(); } }
|
测试类及输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
public class Test { public static void main(String[] args) { ComputerBuilder computerBuilder = new ComputerActualBuilder(); Enterprise enterprise = new Enterprise(); enterprise.setComputerBuilder(computerBuilder); Computer computer = enterprise.assembleComputer("Intel 酷睿i7 8700K", "影驰B360M-M.2", "影驰GAMER 8GB DDR4 2400", "希捷Barracuda 1TB 7200转 64MB", "七彩虹iGame750Ti 烈焰战神U-Twin-2GD5", "金河田峥嵘Z30", "航嘉WD600K", "三星C27F390FHC");
System.out.println(computer); } }
|
测试类的输出结果如下:
Computer{cpu=’Intel 酷睿i7 8700K’, mainboard=’影驰B360M-M.2’, memory=’影驰GAMER 8GB DDR4 2400’, hardDisk=’希捷Barracuda 1TB 7200转 64MB’, gpu=’七彩虹iGame750Ti 烈焰战神U-Twin-2GD5’, crate=’金河田峥嵘Z30’, powerSupply=’航嘉WD600K’, monitor=’三星C27F390FHC’}
类结构图
以上示例类的结构图如下所示

我们可以看到我们的 Test
类和抽象建造者 ComputerBuilder
和产品类 Computer
都没有关系,只和指挥者类 Enterprise
、具体的建造者 ComputerActualBuilder
有关。
Test
类创建指挥者类 Enterprise
,指挥者类 Enterprise
通过组合的方式使用 ComputerBuilder
,实际使用 ComputerActualBuilder
创建产品类 Computer
。
示例演进
上述示例建造者的使用方式只是一种标准的使用方式。
我们发现我们的指挥者类并不是必须的。我们可以不需要攒机商家帮忙组装,我们可以自己动手。
下面来进行代码的演进。
调整产品类
这里使用静态内部类,依靠链式调用的方式来调整产品类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
public class Computer {
private String cpu;
private String mainboard;
private String memory;
private String hardDisk;
private String gpu;
private String crate;
private String powerSupply;
private String monitor;
public Computer(ComputerBuilder computerBuilder) { this.cpu = computerBuilder.cpu; this.mainboard = computerBuilder.mainboard; this.memory = computerBuilder.memory; this.hardDisk = computerBuilder.hardDisk; this.gpu = computerBuilder.gpu; this.crate = computerBuilder.crate; this.powerSupply = computerBuilder.powerSupply; this.monitor = computerBuilder.monitor; }
@Override public String toString() { return "Computer{" + "cpu='" + cpu + '\'' + ", mainboard='" + mainboard + '\'' + ", memory='" + memory + '\'' + ", hardDisk='" + hardDisk + '\'' + ", gpu='" + gpu + '\'' + ", crate='" + crate + '\'' + ", powerSupply='" + powerSupply + '\'' + ", monitor='" + monitor + '\'' + '}'; }
public static class ComputerBuilder {
private String cpu;
private String mainboard;
private String memory;
private String hardDisk;
private String gpu;
private String crate;
private String powerSupply;
private String monitor;
public ComputerBuilder buyCpu(String cpu){ this.cpu = cpu; return this; }
public ComputerBuilder buyMainboard(String mainboard){ this.mainboard = mainboard; return this; }
public ComputerBuilder buyMemory(String memory){ this.memory = memory; return this; }
public ComputerBuilder buyHardDisk(String hardDisk){ this.hardDisk = hardDisk; return this; }
public ComputerBuilder buyGpu(String gpu){ this.gpu = gpu; return this; }
public ComputerBuilder buyCrate(String crate){ this.crate = crate; return this; }
public ComputerBuilder buyPowerSupply(String powerSupply){ this.powerSupply = powerSupply; return this; }
public ComputerBuilder buyMonitor(String monitor){ this.monitor = monitor; return this; }
public Computer build() { return new Computer(this); } } }
|
测试类及输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public class Test { public static void main(String[] args) { Computer computer = new Computer.ComputerBuilder() .buyCpu("Intel 酷睿i7 8700K") .buyMainboard("影驰B360M-M.2") .buyMemory("影驰GAMER 8GB DDR4 2400") .buyHardDisk("希捷Barracuda 1TB 7200转 64MB") .buyGpu("七彩虹iGame750Ti 烈焰战神U-Twin-2GD5") .buyCrate("金河田峥嵘Z30") .buyPowerSupply("航嘉WD600K") .buyMonitor("三星C27F390FHC") .build();
System.out.println(computer); } }
|
测试类的输出结果如下:
Computer{cpu=’Intel 酷睿i7 8700K’, mainboard=’影驰B360M-M.2’, memory=’影驰GAMER 8GB DDR4 2400’, hardDisk=’希捷Barracuda 1TB 7200转 64MB’, gpu=’七彩虹iGame750Ti 烈焰战神U-Twin-2GD5’, crate=’金河田峥嵘Z30’, powerSupply=’航嘉WD600K’, monitor=’三星C27F390FHC’}
类结构图
以上演进的结构图如下所示

源码中的用例
java.lang.StringBuilder
和 java.lang.StringBuffer
Spring
中的 BeanDefinitionBuilder
MyBatis
中的 SqlSessionFactoryBuilder
总结
适用场景
- 一个对象有非常复杂的内部结构(很多属性)
- 想把复杂对象的创建和使用分离
优点
- 封装性比较好,创建和使用分离
- 扩展性好,建造类之间独立,在一定程度上解耦
缺点
- 会产生多余的Builder对象
- 产品内部结构发生变化,建造者都需要修改,成本比较大
参考