前言
当一个类的属性足够多时,且不确定在构造对象时,哪些属性必须,哪些是非必须的。此时,创建该对象这件事情变的不确定。我们也许要排列组合般的写上无数个构造函数,这样显得十分臃肿。此时,一个较为优雅的设计模式应运而生—建造者模式(Builder Pattern)
传统形式
传统的建造者模式由四大部分组成:Product(最终要生成的对象)、Builder(创建着的抽象基类)、ConcreteBuilder(Builder实现类,负责干活)、Director(调用类)
代码示例:
下面是一个Product电脑类,由必须部分和非必须部分组成
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
| @Data public class Computer {
private String cpu;
private String gpu;
private String os;
private String keyboard;
private String display;
public Computer(String cpu, String gpu) { this.cpu = cpu; this.gpu = gpu; }
}
|
定义一个抽象的Builder:
1 2 3 4 5 6 7 8 9
| public interface Builder<T> {
T build();
}
|
定义两个不通品牌电脑的实现:
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
| public class WindowsComputerBuilder implements Builder<Computer> {
private Computer computer;
public WindowsComputerBuilder builder(String cpu, String gpu) { this.computer = new Computer(cpu, gpu); return this; }
public WindowsComputerBuilder os(String os) { computer.setOs(os); return this; }
public WindowsComputerBuilder keyboard(String keyboard) { computer.setKeyboard(keyboard); return this; }
public WindowsComputerBuilder display(String display) { computer.setDisplay(display); return this; }
@Override public Computer build() { 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
| public class MacComputerBuilder implements Builder<Computer> {
private Computer computer;
public MacComputerBuilder builder(String cpu, String gpu) { this.computer = new Computer(cpu, gpu); return this; }
public MacComputerBuilder os(String os) { computer.setOs(os); return this; }
public MacComputerBuilder keyboard(String keyboard) { computer.setKeyboard(keyboard); return this; }
public MacComputerBuilder display(String display) { computer.setDisplay(display); return this; }
@Override public Computer build() { return computer; }
}
|
Director生产两种不同的电脑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Director {
public static void main(String[] args) {
Computer windows = new WindowsComputerBuilder().builder("intel", "rtx") .os("windows") .keyboard("windows键盘") .display("windows显示器").build(); System.out.println(windows); Computer macbook = new MacComputerBuilder().builder("m2", "intel hd") .os("macos") .keyboard("mac键盘") .display("mac显示器").build(); System.out.println(macbook);
}
}
|
可以看到,Builder Pattern生成对象时一般都会执行链式调用,且区分除了必须和非必须的参数
1 2
| Computer(cpu=intel, gpu=rtx, os=windows, keyboard=键盘, display=显示器) Computer(cpu=m2, gpu=intel hd, os=macos, keyboard=键盘, display=显示器)
|
这样做,构建对象时显得更为优雅
JAVA中简化方式
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
| @Data public class Computer {
private String cpu;
private String gpu;
private String os;
private String keyboard;
private String display;
public Computer(Builder builder) { this.cpu = builder.cpu; this.gpu = builder.gpu; this.os = builder.os; this.keyboard = builder.keyboard; this.display = builder.display; }
public static class Builder{
private String cpu; private String gpu; private String os; private String keyboard; private String display;
public Builder(String cpu, String gpu) { this.cpu = cpu; this.gpu = gpu; }
public Builder os(String os) { this.os = os; return this; }
public Builder keyboard(String keyboard) { this.keyboard = keyboard; return this; }
public Builder display(String display) { this.display = display; 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
| public class Director {
public static void main(String[] args) {
Computer windows = new Computer.Builder("intel", "rtx") .os("windows") .keyboard("windows键盘") .display("windows显示器").build(); System.out.println(windows); Computer macbook = new Computer.Builder("m2", "intel hd") .os("macos") .keyboard("mac键盘") .display("mac显示器").build(); System.out.println(macbook);
}
}
|
调用结果:
1 2
| Computer(cpu=intel, gpu=rtx, os=windows, keyboard=windows键盘, display=windows显示器) Computer(cpu=m2, gpu=intel hd, os=macos, keyboard=mac键盘, display=mac显示器)
|
使用工具
lombok
该SDK提供了@Builder注解,可以一键构建对象