Builder - 建造者设计模式

8 阅读3分钟

什么是建造者模式?

建造者模式(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)