什么是建造者模式?
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
为什么要用建造者模式?
在程序中我们往往需要构建一些比较复杂的对象,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化。 构造者模式是将每一个子对象单独提供一个 Builder 类,并且封装其构建过程,这样当需求变化时,我们可以更灵活的去进行组合。
示例
我们先来假设一个场景吧,我比如我们想要一台电脑,那首先会有”显示器”,”主机”等等子组建,那主机内可能还会有”内存”,”处理器”,”磁盘”等等更细节的子组建。那由于电脑一般都会有高配版和低配版,所需的组件可能会发生变化,而且主机的配置也肯能发生变化,这种情况我们如何来解决呢?
为了尽可能缩减代码,我将 Memory, Disk, CPU 抽出了公共属性和方法来定义了一个抽象类 HardWare。主机 (Host) 和显示器 (Display) 为电脑的两个依赖,CPU, Memory, Disk 为 Host 的依赖。
class Computer {
private Display display;
private Host host;
public Computer(Display display, Host host) {
this.display = display;
this.host = host;
}
public String getInfo() {
return "Display: " + this.display.getInfo() + " \n" + this.host.getInfo();
}
}
class Display {
private String type;
private int size;
public Display(String type, int size) {
this.type = type;
this.size = size;
}
public String getInfo() {
return this.type + "(" + this.size + "-inch)";
}
}
class Host {
private Cpu cpu;
private Memory mem;
private Disk disk;
public Host(Cpu cpu, Memory mem, Disk disk) {
this.cpu = cpu;
this.mem = mem;
this.disk = disk;
}
public String getInfo() {
return this.cpu.getInfo() + "\n" + this.mem.getInfo() + "\n" + this.disk.getInfo();
}
}
abstract class HardWare {
public double size;
public String brand, version;
public HardWare(String brand, String version, double size) {
this.brand = brand;
this.version = version;
this.size = size;
}
public abstract String getInfo();
}
class Cpu extends HardWare {
public Cpu(String brand, String version, double size) {
super(brand, version, size);
}
@Override
public String getInfo() {
return "CPU: " + this.brand + " - " + this.version + " | " + this.size + "(GHz)";
}
}
class Memory extends HardWare {
public Memory(String brand, String version, double size) {
super(brand, version, size);
}
@Override
public String getInfo() {
return "Memory: " + this.brand + " - " + this.version + " | " + this.size + "(G)";
}
}
class Disk extends HardWare {
public Disk(String brand, String version, double size) {
super(brand, version, size);
}
@Override
public String getInfo() {
return "Disk: " + this.brand + " - " + this.version + " | " + this.size + "(G)";
}
}
接下来我们来创建一个ComputerBuilder类,此类能够提供两种版本的Computer实例:
abstract class AbstractComputerBuilder {
protected abstract Cpu buildCpu();
protected abstract Disk buildDisk();
protected abstract Display buildDisplay();
protected abstract Memory buildMemory();
protected final Host buildHost() {
return new Host(buildCpu(), buildMemory(), buildDisk());
}
protected final Computer buildComputer() {
return new Computer(buildDisplay(), buildHost());
}
}
class BasicComputerBuilder extends AbstractComputerBuilder {
@Override
protected Cpu buildCpu() {
return new Cpu("Dual-Core", "Intel Core i5", 2.9);
}
@Override
protected Disk buildDisk() {
return new Disk("Apple", "SSD AP0256J", 256);
}
@Override
protected Display buildDisplay() {
return new Display("Retina", 13);
}
@Override
protected Memory buildMemory() {
return new Memory("Apple", "LPDDR3", 4);
}
}
class AdvancedComputerBuilder extends AbstractComputerBuilder {
@Override
protected Cpu buildCpu() {
return new Cpu("Dual-Core", "Intel Core i7", 2.9);
}
@Override
protected Disk buildDisk() {
return new Disk("Apple", "SSD AP0256J", 512);
}
@Override
protected Display buildDisplay() {
return new Display("Retina", 15);
}
@Override
protected Memory buildMemory() {
return new Memory("Apple", "LPDDR3", 16);
}
}
最后我们写一个测试类来输出一下结果:
public static void main(String[] args) {
AbstractComputerBuilder basicBuilder = new BasicComputerBuilder();
System.out.println("***This is a basic version Computer*** \n");
Computer basicVersonComputer = basicBuilder.buildComputer();
System.out.println(basicVersonComputer.getInfo());
System.out.println("\n");
System.out.println("***This is a pro version Computer*** \n");
AbstractComputerBuilder advancedBuilder = new AdvancedComputerBuilder();
Computer proVersionComputer = advancedBuilder.buildComputer();
System.out.println(proVersionComputer.getInfo());
}
Output
***This is a basic version Computer***
Display: Retina(13-inch)
CPU: Dual-Core - Intel Core i5 | 2.9(GHz)
Memory: Apple - LPDDR3 | 4.0(G)
Disk: Apple - SSD AP0256J | 256.0(G)
***This is a pro version Computer***
Display: Retina(15-inch)
CPU: Dual-Core - Intel Core i7 | 2.9(GHz)
Memory: Apple - LPDDR3 | 16.0(G)
Disk: Apple - SSD AP0256J | 512.0(G)