设计模式(Java语言)- 建造者模式

  前言

  在日常的生活中,我们可以经常看到建造者模式的影子。比如,建造房子,那么房子就是一个产品,房子由门,窗,墙,地板等部门组成。然后包工头在建造房子的时候就根据设计好的图纸来建造,但是包工头并不是亲自来建造房子的,而是通过指挥工人来施工。再比如组装电脑,可以根据不同的厂商来组装成不同类型的包括cpu,gpu等都不一样的电脑。

  建造者模式定义

  建造者模式,也称之为创建者模式,将一个复杂的对象的构建和它的表示分离,使得同样的构建过程可以创建出不同的表示,这样的设计模式称之为建造者模式。建造者模式将一个复杂的对象分解成多个简单的对象,然后利用简单的对象一步步构建出复杂的对象。它是变与不变相互分离,即一个产品的组成部分是相同的,但是每个部分产品确实可以依据具体情况来灵活选择。

  建造者模式的应用场景

  需要生成的产品对象具有复杂的内部结构,隔离产品构建和表示,比如:

  1、Java中的java.lang.StringBuilder、java.lang.StringBuffer类使用到了建造者模式。

  2、mybatis 中的SqlSessionFactoryBuilder使用到了建造者模式。

  建造者模式的角色

  1、产品(product):被创建的复杂对象,内部具有多个属性等,由具体的建造者来构建。比如电脑,房子等都是产品角色。

  2、抽象建造者(abstract builder): 抽象建造者是对产品构建过程的规范,比如建造房子需要哪些步骤才可以。类似于房子的设计图纸,所有的房子都是按照图纸建造出来的。

  3、具体建造者(concrete builder):具体建造者构建产品过程中每个步骤的具体体现。比如建造房子是需要地板,那么这个地板是用木板还是瓷砖来做的,都是由具体建造者角色来决定的。

  4、指挥者(director):指挥者就是根据具体建造者的步骤,依据不同的顺序来构建出具体的产品。比如每个包工头建造的房子的顺序都不一样,有的可以要先砌好墙,然后再砌地板,但是无论顺序怎么样,最终造出来的房子是一样的。

  建造者模式UML类图

  设计模式(Java语言)- 建造者模式

 

   代码实现

  首先,我先用上面组装电脑的例子用代码实现一下。

  第一步,创建产品:computer

  

/**
 * @InterfaceName: Computer
 * @description:
 * @author: rainple
 * @create: 2020-05-07 12:42
 **/
public class Computer {


    private String gpu;
    private String cpu;
    private String ram;
    private String mainboard;
    private String power;

    public String getGpu() {
        return gpu;
    }

    public void setGpu(String gpu) {
        this.gpu = gpu;
    }

    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;
    }

    public String getMainboard() {
        return mainboard;
    }

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

    public String getPower() {
        return power;
    }

    public void setPower(String power) {
        this.power = power;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "gpu='" + gpu + '\'' +
                ", cpu='" + cpu + '\'' +
                ", ram='" + ram + '\'' +
                ", mainboard='" + mainboard + '\'' +
                ", power='" + power + '\'' +
                '}';
    }
}

  生成抽象Builder类

/**
 * @className: Builder
 * @description:
 * @author: rainple
 * @create: 2020-05-07 12:45
 **/
public abstract class Builder {

    /**
     * 组装显卡
     */
    abstract void buildGpu();

    /**
     * 组装cpu
     */
    abstract void buildCpu();

    /**
     * 组装内存
     */
    abstract void buildRam();

    /**
     * 组装主板
     */
    abstract void buildMainboard();

    /**
     * 组装电源
     */
    abstract void buildPower();

    /**
     * 获取电脑
     * @return
     */
    abstract Computer getComputer();

}

  创建一个mac电脑

  

/**
 * @className: MacComputer
 * @description:
 * @author: rainple
 * @create: 2020-05-07 12:47
 **/
public class MacComputerBuilder extends Builder {

    private Computer computer;

    public MacComputerBuilder() {
        computer = new Computer();
    }

    @Override
    void buildGpu() {
        computer.setGpu("atx");
        System.out.println("mac book is building gpu");
    }

    @Override
    void buildCpu() {
        computer.setCpu("intel i7");
        System.out.println("mac book is building cpu");
    }

    @Override
    void buildRam() {
        computer.setRam("三星");
        System.out.println("mac book is building ram");
    }

    @Override
    void buildMainboard() {
        computer.setMainboard("microStar");
        System.out.println("mac book is building main board");
    }

    @Override
    void buildPower() {
        computer.setPower("战斧");
        System.out.println("mac book is building power");
    }

    @Override
    Computer getComputer() {
        return computer;
    }
}

  指挥者

/**
 * @className: Derector
 * @description:
 * @author: rainple
 * @create: 2020-05-07 12:52
 **/
public class Director {

    private Builder builder;

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

    public void setBuilder(Builder builder) {
        this.builder = builder;
    }

    /**
     * 组装电脑,组装的顺序可以不同,但是最终组装出来的电脑是一致的
     * @return
     */
    public Computer build() {
        builder.buildGpu();
        builder.buildCpu();
        builder.buildMainboard();
        builder.buildPower();
        builder.buildRam();
        return builder.getComputer();
    }
}

  测试

/**
 * @className: Client
 * @description:
 * @author: rainple
 * @create: 2020-05-07 12:54
 **/
public class Client {

    public static void main(String[] args) {
        Builder builder = new MacComputerBuilder();
        Director director = new Director(builder);
        Computer build = director.build();
        System.out.println(build);
    }

}

  //mac book is building gpu

  //mac book is building cpu

  //mac book is building main board
  //mac book is building power
  //mac book is building ram
  //Computer{gpu='atx', cpu='intel i7', ram='三星', mainboard='microStar', power='战斧'}

 

  当我们在需要创建其它品牌的电脑时,我们只需要集成Builder即可,

/**
 * @className: HuaweiComputer
 * @description:
 * @author: rainple
 * @create: 2020-05-08 12:42
 **/
public class HuaweiComputerBuilder extends Builder {

    private Computer computer;

    public HuaweiComputerBuilder() {
        computer = new Computer();
    }

    @Override
    void buildGpu() {
        computer.setGpu("显卡");
    }

    @Override
    void buildCpu() {
        computer.setCpu("cpu");
    }

    @Override
    void buildRam() {
        computer.setRam("内存");
    }

    @Override
    void buildMainboard() {
        computer.setMainboard("主板");
    }

    @Override
    void buildPower() {
        computer.setPower("电源");
    }

    @Override
    Computer getComputer() {
        return computer;
    }
}

  测试

/**
 * @className: Client
 * @description:
 * @author: rainple
 * @create: 2020-05-07 12:54
 **/
public class Client {

    public static void main(String[] args) {
        Builder builder = new MacComputerBuilder();
        Director director = new Director(builder);
        Computer build = director.build();
        System.out.println(build);
        director.setBuilder(new HuaweiComputerBuilder());
        build = director.build();
        System.out.println(build);
    }

}

  结果:

mac book is building gpu
mac book is building cpu
mac book is building main board
mac book is building power
mac book is building ram
Computer{gpu='atx', cpu='intel i7', ram='三星', mainboard='microStar', power='战斧'}
Computer{gpu='显卡', cpu='cpu', ram='内存', mainboard='主板', power='电源'}

 

  建造者模式的优缺点

  优点:

  1、可以分步构建复杂的对象

  2、能够解决复杂对象内部结构频繁的需求变动的问题

  3、用户新增不同产品时,只需要新增具体的构建者即可,不需要修改原有的产品的构建流程

  缺点:

  1、建造者模式不适用与存有较大差异的产品对象

  2、如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大

  

上一篇:建造者模式


下一篇:行为型模式--访问者模式