Java 设计模式之建造者模式

作者: adm 分类: java 发布时间: 2022-08-09

一、简介
将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

二、实现
在建造者模式中,主要角色如下:

抽象建造者:接口/抽象类 规定要实现复杂对象的创建,但不涉及具体对象的创建。

具体建造者:实现抽象建造者,完成复杂对象的各个部件的具体创建方法,并提供构建好的对象。

指挥者:调用具体建造者来创建复杂对象的各个部分,在指挥者中不涉及具体的产品信息,只负责对象各部分的创建或按照某种顺序创建。

产品:要创建的复杂对象。

举例:

比如我要组装一台电脑,这个电脑由主板,内存,cpu组合而成,而且也是有一定的安装顺序,比如必须要先安装主板再安装cpu,这个过程由指挥者来完成。接下来看代码:

//产品 电脑
public class Computer {
    private String mainBoard;
    private String cpu;
    private String ram;

    public String getMainBoard() {
        return mainBoard;
    }

    public void setMainBoard(String mainBoard) {
        this.mainBoard = mainBoard;
    }

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

    @Override
    public String  toString() {
        return "Computer{" +
                "mainBoard='" + mainBoard + '\'' +
                ", cpu='" + cpu + '\'' +
                ", ram='" + ram + '\'' +
                '}';
    }
}
//抽象建造者类
public abstract class Builder {
    //持有一个产品电脑
    protected Computer computer = new Computer();
    abstract void buildMainBoard(String mainBoard);
    abstract void buildCpu(String cpu);
    abstract void buildRam(String ram);
    abstract Computer build();
}
//具体建造者
public class ComputerBuilder extends Builder{
    //通过具体建造者 设置产品的属性
    @Override
    void buildMainBoard(String mainBoard) {
        computer.setMainBoard("主板:"+mainBoard);
    }

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

    @Override
    void buildRam(String ram) {
        computer.setRam("ram:"+ram);
    }

    @Override
    Computer build() {
        return computer;
    }
}
//指挥者类
public class ComputerDirector {
    //持有一个建造者
    private Builder builder;

    public ComputerDirector(Builder builder){
        this.builder = builder;
    }
    //构建产品 
    public Computer construct(String mainBoard,String cpu,String ram){
        builder.buildMainBoard(mainBoard);
        builder.buildCpu(cpu);
        builder.buildRam(ram);
        return builder.build();
    }
}

使用:

        //创建建造者
        ComputerBuilder builder = new ComputerBuilder();
        //创建指挥者
        ComputerDirector computerDirector = new ComputerDirector(builder);
        //生产产品
        Computer computer = computerDirector.construct("华硕主板","英特尔Cpu","金士顿8G内存");
        System.out.println(computer);

输出:

Computer{mainBoard='主板:华硕主板', cpu='cpu:英特尔Cpu', ram='ram:金士顿8G内存'}

至此,就已经通过建造者模式创建出了我们想要的复杂的产品。其中ComputerDirector有着很重要的作用,它用于指导具体构建的过程或顺序,并返回产品类,但是日常开发中,我们通常会简化它,即把指挥者类和抽象建造者结合。

三、扩展
建造者模式除了上面的用途外,在开发中还有一种常用的方法,上面的computerDirector.construct(“华硕主板”,”英特尔Cpu”,”金士顿8G内存”);传入了很多的参数,如果参数更多怎么办?很容易发生错误可读性变差,接下来看看我们的常用写法。

//产品类
public class Computer {
    private String mainBoard;
    private String cpu;
    private String ram;

    private Computer(Builder builder){
        this.mainBoard = builder.mainBoard;
        this.cpu = builder.cpu;
        this.ram = builder.ram;
    }

    //内部类Builder
    public static final class Builder{
        private String mainBoard;
        private String cpu;
        private String ram;

        public Builder buildMainBoard(String mainBoard){
            this.mainBoard = mainBoard;
            return this;
        }

        public Builder buildCpu(String cpu){
            this.cpu = cpu;
            return this;
        }

        public Builder buildRam(String ram){
            this.ram = ram;
            return this;
        }
        //返回Computer对象
        public Computer build(){
            return new Computer(this);
        }
    }

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

使用:

Computer computer1 = new Computer.Builder()
                .buildMainBoard("华硕主板")
                .buildCpu("英特尔Cpu")
                .buildRam("金士顿8G内存")
                .build();

输出:

Computer{mainBoard='华硕主板', cpu='英特尔Cpu', ram='金士顿8G内存'}

这种方式使用起来更方便,提高开发效率,可以链式调用,再使用一些三方的框架时,其中的链式调用就是这样实现的。

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!