建造者模式主要是用于解决复杂对象的创建问题。在开发复杂的应用程序时,代码往往会变得非常复杂,类会封装更多的功能,类的结构也会变得非常复杂,当我们需要实例化一个复杂的类,以得到不同结构和不同内部状态的对象时,这时,我们可以使用不同的类对它们实例化的算法逻辑进行封装,这些类就叫做建造者类,这样实现实例化复杂对象的逻辑就被放到了单独的建造者类,当需要具有不同结构的对象时,可以采用添加新的建造者类,遵循OCP原则。
建造者模式包含以下几个类:
Product(产品类):需要为其构建对象的类,是具有不同表现形式的复杂或复合对象
Builder(抽象建造者类):用于声明构建产品类的组成部分的抽象类或接口。它的作用仅公开构建产品类的功能,隐藏产品类的其他功能。
ConcreteBuilder(具体建造者类):用于实现抽象建造者类接口中声明的方法,并且提供返回构建好了的产品类的方法。
Director(指导类):用于指导如何构建对象的类,在某些实现方式中可以被移除。导演类可以理解为客户向指导类提出构建产品 的要求,指导类根据客户端要求,指挥具体建造者类组装好产品返回给客户,但如果有时候指导类封装的逻辑过于简单,就可以直接把指导类中封装逻辑移到客户端去,也没有新建一个指导类的必要了;但是,如果抽象产品类和产品类过于复杂的时候,不推荐移除指导类。
使用建造者模式来创建对象,以创建电脑(Computer)对象为例子,事实上,电脑的组装也是比较复杂的,创建类的对象也是一个复杂的操作,根据客户的不同需求,也需要构建不同类型的电脑,比如有:游戏电脑、商务电脑等,现在以构建游戏电脑为例子,UML图如下:
Product(产品类):Computer
Builder(抽象建造者类):ComputerBuilder
ConcreteBuilder(具体建造者类):GameComputerBuilder
Director(指导类):ComputerDirector
具体代码如下:
1、定义产品类Computer
package com.bran.builder.type1;
public class Computer {
private String cpu;
private String memory;
private String disk;
private String gpu;
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
public String getDisk() {
return disk;
}
public void setDisk(String disk) {
this.disk = disk;
}
public String getGpu() {
return gpu;
}
public void setGpu(String gpu) {
this.gpu = gpu;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", memory='" + memory + '\'' +
", disk='" + disk + '\'' +
", gpu='" + gpu + '\'' +
'}';
}
}
2、定义抽象建造者类ComputerBuilder,声明构建电脑的组成部分
package com.bran.builder.type1;
public interface ComputerBuilder {
void buildCpu();
void buildMemory();
void buildDisk();
void buildGpu();
Computer builderComputer();
}
3、新建具体建造者类GameComputerBuilder,主要封装构建游戏电脑的逻辑细节,以实现构建和装配该类型产品的各个组件,并提供返回构建好的产品的方法buildComputer()
package com.bran.builder.type1;
public class GameComputerBuilder implements ComputerBuilder{
private Computer computer;
public GameComputerBuilder() {
computer = new Computer();
}
@Override
public void buildCpu() {
computer.setCpu("至强W-3175X");
}
@Override
public void buildMemory() {
computer.setMemory("16GB");
}
@Override
public void buildDisk() {
computer.setDisk("1TB");
}
@Override
public void buildGpu() {
computer.setGpu("RTX 2080Ti");
}
@Override
public Computer builderComputer() {
return computer;
}
}
4、定义指导类ComputerDirector,使用ComputerBuilder接口来完成产品的装配
package com.bran.builder.type1;
public class ComputerDirector {
public Computer constructGameComputer(ComputerBuilder computerBuilder){
computerBuilder.buildCpu();
computerBuilder.buildDisk();
computerBuilder.buildMemory();
computerBuilder.buildGpu();
return computerBuilder.builderComputer();
}
}
5、测试使用构建者模式
package com.bran.builder.type1;
public class BuilderTest {
public static void main(String[] args) {
ComputerDirector computerDirector = new ComputerDirector();
ComputerBuilder gameComputerBuilder = new GameComputerBuilder();
Computer computer = computerDirector.constructGameComputer(gameComputerBuilder);
System.out.println(computer);
}
}
注意:建造者模式与工厂模式的最大区别是,建造者模式更注重产品的组合方式和装配顺序,而工厂模式关注产品生产本身