一、简介
将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
二、实现
在建造者模式中,主要角色如下:
抽象建造者:接口/抽象类 规定要实现复杂对象的创建,但不涉及具体对象的创建。
具体建造者:实现抽象建造者,完成复杂对象的各个部件的具体创建方法,并提供构建好的对象。
指挥者:调用具体建造者来创建复杂对象的各个部分,在指挥者中不涉及具体的产品信息,只负责对象各部分的创建或按照某种顺序创建。
产品:要创建的复杂对象。
举例:
比如我要组装一台电脑,这个电脑由主板,内存,cpu组合而成,而且也是有一定的安装顺序,比如必须要先安装主板再安装cpu,这个过程由指挥者来完成。接下来看代码:
//产品 电脑
public class Computer {
private String mainBoard;
private String cpu;
private String ram;
public String getMainBoard() {
return mainBoard;
}
public void setMainBoard(String mainBoard) {
this.mainBoard = mainBoard;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getRam() {
return ram;
}
public void setRam(String ram) {
this.ram = ram;
}
@Override
public String toString() {
return "Computer{" +
"mainBoard='" + mainBoard + '\'' +
", cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
'}';
}
}
//抽象建造者类
public abstract class Builder {
//持有一个产品电脑
protected Computer computer = new Computer();
abstract void buildMainBoard(String mainBoard);
abstract void buildCpu(String cpu);
abstract void buildRam(String ram);
abstract Computer build();
}
//具体建造者
public class ComputerBuilder extends Builder{
//通过具体建造者 设置产品的属性
@Override
void buildMainBoard(String mainBoard) {
computer.setMainBoard("主板:"+mainBoard);
}
@Override
void buildCpu(String cpu) {
computer.setCpu("cpu:"+cpu);
}
@Override
void buildRam(String ram) {
computer.setRam("ram:"+ram);
}
@Override
Computer build() {
return computer;
}
}
//指挥者类
public class ComputerDirector {
//持有一个建造者
private Builder builder;
public ComputerDirector(Builder builder){
this.builder = builder;
}
//构建产品
public Computer construct(String mainBoard,String cpu,String ram){
builder.buildMainBoard(mainBoard);
builder.buildCpu(cpu);
builder.buildRam(ram);
return builder.build();
}
}
使用:
//创建建造者
ComputerBuilder builder = new ComputerBuilder();
//创建指挥者
ComputerDirector computerDirector = new ComputerDirector(builder);
//生产产品
Computer computer = computerDirector.construct("华硕主板","英特尔Cpu","金士顿8G内存");
System.out.println(computer);
输出:
Computer{mainBoard='主板:华硕主板', cpu='cpu:英特尔Cpu', ram='ram:金士顿8G内存'}
至此,就已经通过建造者模式创建出了我们想要的复杂的产品。其中ComputerDirector有着很重要的作用,它用于指导具体构建的过程或顺序,并返回产品类,但是日常开发中,我们通常会简化它,即把指挥者类和抽象建造者结合。
三、扩展
建造者模式除了上面的用途外,在开发中还有一种常用的方法,上面的computerDirector.construct("华硕主板","英特尔Cpu","金士顿8G内存");传入了很多的参数,如果参数更多怎么办?很容易发生错误可读性变差,接下来看看我们的常用写法。
//产品类
public class Computer {
private String mainBoard;
private String cpu;
private String ram;
private Computer(Builder builder){
this.mainBoard = builder.mainBoard;
this.cpu = builder.cpu;
this.ram = builder.ram;
}
//内部类Builder
public static final class Builder{
private String mainBoard;
private String cpu;
private String ram;
public Builder buildMainBoard(String mainBoard){
this.mainBoard = mainBoard;
return this;
}
public Builder buildCpu(String cpu){
this.cpu = cpu;
return this;
}
public Builder buildRam(String ram){
this.ram = ram;
return this;
}
//返回Computer对象
public Computer build(){
return new Computer(this);
}
}
@Override
public String toString() {
return "Computer{" +
"mainBoard='" + mainBoard + '\'' +
", cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
'}';
}
}
使用:
Computer computer1 = new Computer.Builder()
.buildMainBoard("华硕主板")
.buildCpu("英特尔Cpu")
.buildRam("金士顿8G内存")
.build();
输出:
Computer{mainBoard='华硕主板', cpu='英特尔Cpu', ram='金士顿8G内存'}
这种方式使用起来更方便,提高开发效率,可以链式调用,再使用一些三方的框架时,其中的链式调用就是这样实现的。
网友评论