3_建造者模式

3_建造者模式

简述:建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

也就是说不仅仅是关注 new 对象的结果,更注重对象属性的赋值过程!

实体类 #:

public class Computer {
    private  String cpu;
    private String gpu;
    private String memory;
    private  String Hd;

    public String getCpu() {
        return cpu;
    }

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

    public String getGpu() {
        return gpu;
    }

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

    public String getHd() {
        return Hd;
    }

    public void setHd(String hd) {
        Hd = hd;
    }

    public String getMemory() {
        return memory;
    }

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

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", gpu='" + gpu + '\'' +
                ", memory='" + memory + '\'' +
                ", Hd='" + Hd + '\'' +
                '}';
    }
}
反例 #1 :

现在开始创建对象 。

public class Negative {
    public static void main(String[] args) {
        Computer computer1 = new Computer();
        computer1.setCpu("9700k");
        computer1.setGpu("gtx2080ti");
        computer1.setMemory("16g");
        computer1.setHd("机械1T");

        Computer computer2 = new Computer();
        computer2.setCpu("9600k");
        computer2.setGpu("gtx1080ti");
        computer2.setMemory("32g");
        computer2.setHd("固态500G");

        System.out.println(computer1);
        System.out.println(computer2);
    }
}

缺陷: 建造复杂对象的时候,客户端程序要炸,造成客户端代码臃肿,且违反迪米特法则(最少知道原则) 。

反例 #2:

将属性赋值过程使用一个建造类封装起来,但此时仍然还不是建造者模式 。

public class Negative2 {
    /*=============服务端==========================*/
    static class HighComputerBuilder {
        private Computer computer = new Computer();

        public Computer build() {
            computer.setCpu("9700k");
            computer.setGpu("gtx2080ti");
            computer.setHd("固态1T");
            computer.setMemory("32G");
            return computer;
        }
    }

    static class MiddleComputerBuilder {
        private Computer computer = new Computer();

        public Computer build() {
            computer.setCpu("9600k");
            computer.setGpu("gtx1080ti");
            computer.setHd("固态500G");
            computer.setMemory("16G");
            return computer;
        }
    }
    /*=====================客户端===============================*/
    public static void main(String[] args) {
        HighComputerBuilder builder1 = new HighComputerBuilder();
        Computer computer1 =builder1.build();

        MiddleComputerBuilder builder2 = new MiddleComputerBuilder();
        Computer computer2 =builder2.build();

        System.out.println(computer1);
        System.out.println(computer2);
    }
}

UML类图如下:

在这里插入图片描述

缺陷:建造者遗漏部分建造步骤,编译也会通过,会造成建造出来的对象不符合要求。比如,漏执行某一步骤时,使得部分值为 null ,后续对象属性被调用时,可能会抛出空指针NullPointerException异常,会造成程序崩溃。

反例 #3:

定义一个建造者接口来进行规范 。

public class Negative3 {
    /*=============服务端==========================*/
    /***定义一个建造者接口进行规范****/
    interface ComputerBuilder{
        Computer build();
        void setCpu();
        void setGpu();
        void setMemory();
        void setHd();
    }
    
    static class HighComputerBuilder implements ComputerBuilder{

        private Computer computer = new Computer();

        @Override
        public void setCpu() {
            computer.setCpu("9700k");
        }

        @Override
        public void setGpu() {
            computer.setGpu("gtx2080ti");
        }

        @Override
        public void setMemory() {
            computer.setMemory("32G");
        }

        @Override
        public void setHd() {
            computer.setHd("固态1T");
        }

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

    static class MiddleComputerBuilder implements ComputerBuilder{

        private Computer computer = new Computer();

        @Override
        public void setCpu() {
            computer.setCpu("9500k");
        }

        @Override
        public void setGpu() {
            computer.setGpu("gtx1060ti");
        }

        @Override
        public void setMemory() {
            computer.setMemory("16G");
        }

        @Override
        public void setHd() {
            computer.setHd("固态500G");
        }

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

    /*==============客户端=====================================*/
    public static void main(String[] args) {
        HighComputerBuilder builder1 = new HighComputerBuilder();
        builder1.setCpu();
        builder1.setGpu();
        builder1.setHd();
        builder1.setMemory();
        Computer computer1 =builder1.build();

        MiddleComputerBuilder builder2 = new MiddleComputerBuilder();
        builder2.setCpu();
        builder2.setGpu();
        builder2.setHd();
        builder2.setMemory();
        Computer computer2 =builder2.build();

        System.out.println(computer1);
        System.out.println(computer2);
    }
}

创造了建造者接口,创建者不会再遗漏步骤。

UML类图如下:

在这里插入图片描述

缺陷:

  • 每一个builder都要自己去调用setXXX方法进行创建,造成代码重复。
  • 需要客户端自己执行创建步骤,建造复杂对象的时候,容易造成客户端代码臃肿,且违反迪米特法则(最少知道原则)。而且客户端会出现遗漏步骤的情况。感觉又回到了原点 。
正例 #1:

将属性赋值步骤,交给一个指挥者,让它去指挥建造者完成,我们只需要安排指挥者就行 。

public class Negative3 {
    /*=============服务端==========================*/
    interface ComputerBuilder {
        Computer build();

        void setCpu();

        void setGpu();

        void setMemory();

        void setHd();
    }

    static class HighComputerBuilder implements ComputerBuilder {

        private Computer computer = new Computer();

        @Override
        public void setCpu() {
            computer.setCpu("9700k");
        }

        @Override
        public void setGpu() {
            computer.setGpu("gtx2080ti");
        }

        @Override
        public void setMemory() {
            computer.setMemory("32G");
        }

        @Override
        public void setHd() {
            computer.setHd("固态1T");
        }

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

    static class MiddleComputerBuilder implements ComputerBuilder {

        private Computer computer = new Computer();

        @Override
        public void setCpu() {
            computer.setCpu("9500k");
        }

        @Override
        public void setGpu() {
            computer.setGpu("gtx1060ti");
        }

        @Override
        public void setMemory() {
            computer.setMemory("16G");
        }

        @Override
        public void setHd() {
            computer.setHd("固态500G");
        }

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

    //--------------指挥者---------------//
    static class Director {
        public Computer build(ComputerBuilder builder) {
            builder.setCpu();
            builder.setGpu();
            builder.setMemory();
            builder.setHd();
            return builder.build();
        }
    }


    /*==============客户端=====================================*/
    public static void main(String[] args) {

        HighComputerBuilder hcb = new HighComputerBuilder();
        MiddleComputerBuilder mcb = new MiddleComputerBuilder();

        Director director = new Director();
        Computer computer1 = director.build(hcb);
        Computer computer2 = director.build(mcb);

        System.out.println(computer1);
        System.out.println(computer2);
    }
}

UML类图如下:
在这里插入图片描述

此时在需要增加一个不同配置的 LowComputer 类型计算机,只需要编写一个LowComputerBuilder类实现 ComputerBuilder 接口,再传给指挥者 Director 进行创建即可得到一个 LowComputer 类型的 Computer 对象。符合开闭原则 。

总结一下建造者模式的优点:

  • 创建对象的过程保持稳定。(通过 ComputerBuilder 接口保持稳定)
  • 创建过程只需要编写一次(通过实现 ComputerBuilder 接口的类保持稳定)
  • 保持扩展性,需要创建新类型的对象时,只需要创建新的 Builder ,再使用指挥者 Director 进行调用进行创建即可。
  • 增加指挥者 Director 保证步骤稳定执行,客户端不需要知道创建对象的具体步骤,符合迪米特法则(最少知道原则)。

建造者模式和工厂模式的区别

  • 工厂模式注重new一个对象就可以,是否得到了这一对象,更多地关注new的结果。
  • 建造者模式注重保证new的对象稳定可用,保证不出现细节缺漏,更多关注new的细节、过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值