Loading

建造者模式

建造者模式

简介

定义:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

表示用人话讲就是同一类物体,不同的表现形式。比如电脑,有高配的,中配的,低配的。这些不同的配置级别就是不同的表示。

主要作用:

在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。

如何使用:

用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)。

解决的问题:

  • 方便用户创建复杂的对象(不需要知道实现过程)
  • 代码复用性 & 封装性(将对象构建过程和细节进行封装 & 复用)

注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序,一般用来创建更为复杂的对象

建造者模式推导

1、先建一个computer的实体类,代表要建造的对象

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

    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 getRAM() {
        return RAM;
    }

    public void setRAM(String RAM) {
        this.RAM = RAM;
    }

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

推导1

public class Test {
    public static void main(String[] args) {
        Computer computer_01 = new Computer();
        computer_01.setCpu("9700k");
        computer_01.setGpu("gtx2080ti");
        computer_01.setHd("SSD--1T");
        computer_01.setRAM("32G");

        Computer computer_02 = new Computer();
        computer_02.setCpu("9600k");
        computer_02.setGpu("gtx1080ti");
        computer_02.setHd("SSD--500G");
        computer_02.setRAM("16G");

        System.out.println(computer_02);
        System.out.println(computer_01);
    }
}

上述代码中,对象的创建全部由客户端来做,代码及其臃肿,且也违反了迪米特法则。这就像一个人去电脑城配电脑,要配什么全部都由顾客来做,这是不正确的。

推导2

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

        public Computer build() {
            computer.setCpu("9700k");
            computer.setGpu("gtx2080ti");
            computer.setHd("SSD--1T");
            computer.setRAM("32G");
            return computer;
        }
    }

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

        public Computer build() {
            computer.setCpu("9600k");
            computer.setHd("SSD--500G");
            computer.setRAM("16G");
            return computer;
        }
    }
/*=====================客户端===============================*/
    public static void main(String[] args) {
        HighComputerBuilder hcb = new HighComputerBuilder();
        Computer highComputerBuilder =hcb.build();

        LowComputerBuilder lcb = new LowComputerBuilder();
        Computer lowComputerBuilder =lcb.build();

        System.out.println(hcb);
        System.out.println(lcb);
    }
}

上述代码解决了推导1中构造电脑由客户端来完成的问题,但还有一些缺陷,比如在完成LowComputer建造的时候,店家忘记配置computer.setGpu("gtx1050");显卡了,那么导致的结果就是顾客拿回去的电脑是不完整的,这样是不可信的,所以我们还需要继续改进。

推导3

public class Test {
    /*=============服务端==========================*/
    interface ComputerBuilder{
        Computer build();
        void setCpu();
        void setGpu();
        void setHd();
        void setRAM();
    }

    static class HighComputerBuilder implements ComputerBuilder{
        private Computer computer = new Computer();

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

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

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

        @Override
        public void setHd() {
            computer.setHd("SSD--1T");
        }

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

    static class LowComputerBuilder implements ComputerBuilder{
        private Computer computer = new Computer();

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

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

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

        @Override
        public void setHd() {
            computer.setHd("SSD--500G");
        }

        @Override
        public void setRAM() {
            computer.setRAM("16G");
        }
    }
    /*==============客户端=====================================*/
    public static void main(String[] args) {
        HighComputerBuilder hcb = new HighComputerBuilder();
        hcb.setCpu();
        hcb.setGpu();
        hcb.setHd();
        hcb.setRAM();
        Computer computer_01 =hcb.build();

        LowComputerBuilder lcb = new LowComputerBuilder();
        lcb.setCpu();
        lcb.setGpu();
        lcb.setHd();
        lcb.setRAM();
        Computer computer_02 =lcb.build();

        System.out.println(computer_01);
        System.out.println(computer_02);
    }
}

interface ComputerBuilder这个接口就像是配电脑的一个规约,配电脑的时候必须遵守,这就解决了上述可能会遗漏步骤的问题。

在上述中每一个builder都要自己去调用setXXX方法进行创建,造成代码重复。需要客户端自己执行创建步骤,建造复杂对象的时候,容易造成客户端代码臃肿,且违反迪米特法则。而且客户端会出现遗漏步骤的情况。貌似也和上一步一样了。

这个时候就需要一个指挥者身份的人来帮忙创建好这些对象,来解决这些问题。

推导4

public class postive {
    /*=============服务端==========================*/
    interface ComputerBuilder{
        Computer getComputer();
        void setCpu();
        void setGpu();
        void setHd();
        void setRAM();
    }

    static class HighComputerBuilder implements ComputerBuilder {
        private Computer computer = new Computer();

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

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

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

        @Override
        public void setHd() {
            computer.setHd("SSD--1T");
        }

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

    static class LowComputerBuilder implements ComputerBuilder {
        private Computer computer = new Computer();

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

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

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

        @Override
        public void setHd() {
            computer.setHd("SSD--500G");
        }

        @Override
        public void setRAM() {
            computer.setRAM("16G");
        }
    }
    
	//指挥者
    static class Director {

        public Computer build(ComputerBuilder builder){
            builder.setCpu();
            builder.setGpu();
            builder.setRAM();
            builder.setHd();
            return builder.getComputer();
        }
    }
    /*==============客户端=====================================*/
    public static void main(String[] args) {
        Director director = new Director();

        Computer computer_01 =director.build(new HighComputerBuilder());
        Computer computer_02 =director.build(new LowComputerBuilder());

        System.out.println(computer_01);
        System.out.println(computer_02);
    }
}

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

这个过程就像你要去电脑城配电脑,老板告诉你有两种配置,然后你选一种,选好后老板指挥装机的小哥帮你组装好。老板就相当于Director,装机小哥就相当于XXXComputerBuilder

UML类图

image-20210313185754673

总结

建造者模式的优点:

  • 创建对象的过程保持稳定。(通过ComputerBuilder接口保持稳定)
  • 创建过程只需要编写一次(通过实现ComputerBuilder接口的类保持稳定)
  • 保持扩展性,需要创建新类型的对象时,只需要创建新的Builder,再使用指挥者Director进行调用进行创建即可。
  • 增加指挥者Director保证步骤稳定执行,客户端不需要知道创建对象的具体步骤,符合迪米特法则
posted @ 2021-03-13 18:59  nuoxin  阅读(90)  评论(0)    收藏  举报