探究常用设计模式(四)建造者模式

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
话不多说,上demo
先构建一个电脑实体类

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 + '\'' +
                '}';
    }
}

此时,如果我们要组装一台电脑

public class negtive_01 {
    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);
    }
}

很明显,这违反了迪米特法则,即最少知道原则,为了解决这个问题,我们可以在服务器端先对这个复杂的组装过程进行封装

public class negtive_02 {
    /*=============服务端==========================*/
    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 High_02ComputerBuilder {
        private Computer computer = new Computer();

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

        High_02ComputerBuilder builder_02 = new High_02ComputerBuilder();
        Computer computer_02 =builder_02.build();

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

但是问题又来了,大量重复的代码会导致容错率变低,使得建造组装的过程不稳定,如果服务器少配置了一个参数怎么办?不过这并不是什么问题,有点经验的程序猿都知道,再抽象一个类就好了嘛。这就演变出了建造者模式的雏形,我们看看代码实现:

public class negtive_03 {
    /*=============服务端==========================*/
    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 High_02ComputerBuilder 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 builder_01 = new HighComputerBuilder();
        builder_01.setCpu();
        builder_01.setGpu();
        builder_01.setHd();
        builder_01.setRAM();
        Computer computer_01 =builder_01.build();

        High_02ComputerBuilder builder_02 = new High_02ComputerBuilder();
        builder_02.setCpu();
        builder_02.setGpu();
        builder_02.setHd();
        builder_02.setRAM();
        Computer computer_02 =builder_02.build();

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

问题看似解决了,不过小伙伴仔细想想,全权交给客户端来做是不安全的,并且这不又回到违反迪米特法则的原点了吗?

看来这条路走不通了,下面我们来采用建造者模式实现,

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 High_02ComputerBuilder 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 High_02ComputerBuilder());

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

现在我们封装一个指挥者,让指挥者来做之前客户端需要做的事,然后返回一个客户端需要的对象。此时在需要增加一个不同配置的A_Computer类型计算机,只需要编写一个A_Builder类实现ComputerBuilder接口,再传给指挥者Director进行创建即可得到一个A_Computer类型的Computer对象。符合开闭原则。UML类图如下:
在这里插入图片描述
总结

  • 模式的应用场景

建造者模式唯一区别于工厂模式的是针对复杂对象的创建。也就是说,如果创建简单对象,通常都是使用工厂模式进行创建,而如果创建复杂对象,就可以考虑使用建造者模式。

当需要创建的产品具备复杂创建过程时,可以抽取出共性创建过程,然后交由具体实现类自定义创建流程,使得同样的创建行为可以生产出不同的产品,分离了创建与表示,使创建产品的灵活性大大增加。

建造者模式主要适用于以下应用场景:

  • 相同的方法,不同的执行顺序,产生不同的结果。 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
  • 产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。

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

通过前面的学习,我们已经了解了建造者模式,那么它和工厂模式有什么区别呢?

  • 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
  • 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
  • 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
  • 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。

模式的扩展
建造者(Builder)模式在应用过程中可以根据需要改变,如果创建的产品种类只有一种,只需要一个具体建造者,这时可以省略掉抽象建造者,甚至可以省略掉指挥者角色

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值