创建型-建造者模式 (Builder Pattern)

开课吧樵夫2021-12-07 14:59

  本篇开始建造者模式的学习。建造者模式是开发中接触比较频繁的一种设计模式,像常见的有 Mockito 框架、Spring Security 框架、StringBuilder类等。

  什么是建造者模式

  建造者模式也叫生成器模式,指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示 。

  它将一个复杂的对象分解成多个简单的对象,一步一步构建,使用户通过指定复杂对象的类型和内容就可以构建它们,不需要知道内部的具体构建细节。

  建造者模式(Builder Pattern)

  这里以电脑为例,电脑有四大组件主板、CPU、内存、磁盘,不同配置的组件就可以组成不同的电脑。如下图所示:

创建型-建造者模式 (Builder Pattern)

  四大角色:

  Product:多个组成部件的复杂对象

  Builder:抽象建造者,负责定义通用方法和构建方法

  ConcreteBuilder:具体建造者, 负责复杂产品的各个部件的具体创建

  Director:指挥者,负责整个组合流程

  第一步:创建部件产品

/**
 * 主板
 */
public class Mainboard {
    // 省略主板细节...
}

/**
 * CPU
 */
public class CPU {
    // 省略CPU细节...
}

/**
 * 内存
 */
public class Memory {
    // 省略内存细节...
}

/**
 * 硬盘
 */
public class Disk {
    // 省略硬盘细节...
}

  ps:由于每个组件本身就有自己的属性,在本文中就不做对象细节设计了。

  第二步:创建Product

/**
 * Product:电脑
 */
public class Computer {

    private Mainboard mainboard;

    private CPU cpu;

    private Memory memory;

    private Disk disk;

    public Mainboard getMainboard() {
        return mainboard;
    }

    public void setMainboard(Mainboard mainboard) {
        this.mainboard = mainboard;
    }

    public CPU getCpu() {
        return cpu;
    }

    public void setCpu(CPU cpu) {
        this.cpu = cpu;
    }

    public Memory getMemory() {
        return memory;
    }

    public void setMemory(Memory memory) {
        this.memory = memory;
    }

    public Disk getDisk() {
        return disk;
    }

    public void setDisk(Disk disk) {
        this.disk = disk;
    }

    @Override
    public String toString() {
        return "Product{" +
                "mainboard=" + mainboard +
                ", cpu=" + cpu +
                ", memory=" + memory +
                ", disk=" + disk +
                '}';
    }
}

  第三步:定义抽象构建者

/**
 * 抽象构建者
 * 负责定义通用方法和构建方法
 */
public interface Builder {

    /**
     * 构建主板
     * @param mainboard
     */
    void buildMainboard(Mainboard mainboard);

    /**
     * 构建CPU
     * @param cpu
     */
    void buildCPU(CPU cpu);

    /**
     * 构建内存
     * @param memory
     */
    void buildMemory(Memory memory);

    /**
     * 构建磁盘
     * @param disk
     */
    void buildDisk(Disk disk);

    /**
     * 构建产品
     * @return Computer
     */
    Computer create();
}

  第四步:创建具体构建者

/**
 * 具体建造者, 负责复杂产品的各个部件的具体创建
 */
public class ConcreteBuilder implements Builder {

    private Computer computer = new Computer();


    @Override
    public void buildMainboard(Mainboard mainboard) {
        this.computer.setMainboard(mainboard);
    }

    @Override
    public void buildCPU(CPU cpu) {
        this.computer.setCpu(cpu);
    }

    @Override
    public void buildMemory(Memory memory) {
        this.computer.setMemory(memory);
    }

    @Override
    public void buildDisk(Disk disk) {
        this.computer.setDisk(disk);
    }

    @Override
    public Computer create() {
        return computer;
    }
}

  第五步:创建指挥者

/**
 * 指挥者
 */
public class Director {

    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public Computer build(Mainboard mainboard, CPU cpu, Memory memory, Disk disk) {
        builder.buildMainboard(mainboard);
        builder.buildCPU(cpu);
        builder.buildMemory(memory);
        builder.buildDisk(disk);
        return builder.create();
    }
}

  第六步:测试

public class BuildTest {

    public static void main(String[] args) {
        Director director = new Director(new ConcreteBuilder());
        Computer computer = director.build(new Mainboard(), new CPU(), new Memory(), new Disk());
        System.out.println(computer);
    }
}

  测试结果:

Product{mainboard=com.ksoeun.javafamily.Mainboard@1e643faf, cpu=com.javafamily.builder.CPU@6e8dacdf, memory=com.javafamily.builder.Memory@7a79be86, disk=com.javafamily.builder.Disk@34ce8af7}

  优点:

  符合开闭原

  则用户不必知道产品内部组合的细节

  将产品本身与其创建过程解耦

  每一个具体建造者都相对独立,可控制产品的创建过程粒度更小

  缺点:

  只适用于共同点较多的产品

  建造者模式优化

  现在流行的一些开源框架和JDK的类,对构造器模式的运用,一般都是使用优化版的建造者模式。

  优化版的建造者模式只需要修改上面的 Builder 和 ConcreteBuilder。

  第一步:修改 Builder 将返回值改为自身

/**
 * 优化版抽象构建者
 * 负责定义通用方法和构建方法
 */
public interface OptimizedBuilder {

    /**
     * 构建主板
     * @param mainboard
     */
    OptimizedBuilder buildMainboard(Mainboard mainboard);

    /**
     * 构建CPU
     * @param cpu
     */
    OptimizedBuilder buildCPU(CPU cpu);

    /**
     * 构建内存
     * @param memory
     */
    OptimizedBuilder buildMemory(Memory memory);

    /**
     * 构建磁盘
     * @param disk
     */
    OptimizedBuilder buildDisk(Disk disk);

    /**
     * 构建产品
     * @return Computer
     */
    Computer create();
}

  第二步:修改 ConcreteBuilder build方法返回当前对象

/**
 * 优化版构建者模式
 * 具体建造者, 负责复杂产品的各个部件的具体创建
 */
public class OptimizedConcreteBuilder implements OptimizedBuilder {

    private Computer computer = new Computer();


    @Override
    public OptimizedBuilder buildMainboard(Mainboard mainboard) {
        this.computer.setMainboard(mainboard);
        return this;
    }

    @Override
    public OptimizedBuilder buildCPU(CPU cpu) {
        this.computer.setCpu(cpu);
        return this;
    }

    @Override
    public OptimizedBuilder buildMemory(Memory memory) {
        this.computer.setMemory(memory);
        return this;
    }

    @Override
    public OptimizedBuilder buildDisk(Disk disk) {
        this.computer.setDisk(disk);
        return this;
    }

    @Override
    public Computer create() {
        return computer;
    }
}

  第三步:测试

public class BuildTest {

    public static void main(String[] args) {
        Computer computer = new OptimizedConcreteBuilder()
                .buildMainboard(new Mainboard())
                .buildCPU(new CPU())
                .buildMemory(new Memory())
                .buildDisk(new Disk())
                .create();
        System.out.println(computer);
    }
}

  测试结果:  

Product{mainboard=com.javafamily.builder.Mainboard@3b6eb2ec, cpu=com.javafamily.builder.CPU@1e643faf, memory=com.javafamily.builder.Memory@6e8dacdf, disk=com.javafamily.builder.Disk@7a79be86}

  以上就是开课吧小编为大家整理发布的“创建型-建造者模式 (Builder Pattern)”一文,更多相关内容尽在开课吧广场Java教程频道。

创建型-建造者模式 (Builder Pattern)

免责声明:本站所提供的内容均来源于网友提供或网络搜集,由本站编辑整理,仅供个人研究、交流学习使用。如涉及版权问题,请联系本站管理员予以更改或删除。
有用
分享