创建型设计模式之构建器模式(Builder)

设计模式之构建器模式

建造者模式,顾名思义就是要构建某一个产品。但是这个模式与工厂方法模式和抽象工厂模式的侧重点是不同,具体怎么不同,先来看一段例子:假设有一个生产飞机的工厂,每天做的当然是生产飞机零件、组装飞机等一系列的操作,只要收到订单,那么就要开始生产。现在有个奇葩的客户,要求按照他的想法组装飞机;隔断时间又有一个奇葩客户,要求按照他的想法组装飞机,为了满足客户的需求,再苦再难也要搞啊。
下面将这个例子用代码进行实现:

public class Builder_01 {

    //飞机抽象类
    static abstract class Airplane{
        private List<String> sequences;
        //组装引擎
        protected abstract void assembleEnginee();
        //组装机身
        protected abstract void assembleBody();
        //组装控制台
        protected abstract void assembleControl();
        //组装武器
        protected abstract void assembleWeapon();

        public void finish(){
            if(null!=this.sequences && this.sequences.size()>0){
                for (String sequence : this.sequences) {
                    switch (sequence.toLowerCase()){
                        case "enginee": this.assembleEnginee();break;
                        case "body": this.assembleBody();break;
                        case "control": this.assembleControl();break;
                        case "weapon": this.assembleWeapon();break;
                        default:break;
                    }
                }
            }
        }

        public void setSequences(List<String> sequences){
            this.sequences = sequences;
        }
    }

    //歼-7前线机
    static class AnnihilatSevenAirplane extends Airplane{
        @Override
        protected void assembleEnginee() {
            System.out.println("组装歼-7前线机引擎");
        }

        @Override
        protected void assembleBody() {
            System.out.println("组装歼-7前线机机身");
        }

        @Override
        protected void assembleControl() {
            System.out.println("组装歼-7前线机控制台");
        }

        @Override
        protected void assembleWeapon() {
            System.out.println("组装歼-7前线机武器");
        }
    }
    //歼-8高空高速截击机
    static class AnnihilatEightAirplane extends Airplane{
        @Override
        protected void assembleEnginee() {
            System.out.println("组装歼-8高空高速截击机引擎");
        }

        @Override
        protected void assembleBody() {
            System.out.println("组装歼-8高空高速截击机机身");
        }

        @Override
        protected void assembleControl() {
            System.out.println("组装歼-8高空高速截击机控制台");
        }

        @Override
        protected void assembleWeapon() {
            System.out.println("组装歼-8高空高速截击机武器");
        }
    }

    public static void main(String[] args) {
        //开始提供组装顺序
        List<String> sequences = new ArrayList<>();
        sequences.add("enginee");
        sequences.add("body");
        sequences.add("control");
        sequences.add("weapon");
        AnnihilatEightAirplane annihilatEightAirplane = new AnnihilatEightAirplane();
        annihilatEightAirplane.setSequences(sequences);
        annihilatEightAirplane.finish();
        System.out.println("==========================================================");
        sequences.clear();
        sequences.add("control");
        sequences.add("body");
        sequences.add("enginee");
        sequences.add("weapon");
        AnnihilatSevenAirplane annihilatSevenAirplane = new AnnihilatSevenAirplane();
        annihilatSevenAirplane.setSequences(sequences);
        annihilatSevenAirplane.finish();
    }
}

由于每个飞机的主要部件相同,所有抽象出四个方法,分别代表组装不同的部件。同时由于需要根据客户提供的组装顺序进行组装,这里提供一个具体方法(模板方法模式),封装组装步骤,由具体的飞机来实现各自部件组装逻辑。
运行以上代码:

组装歼-8高空高速截击机引擎
组装歼-8高空高速截击机机身
组装歼-8高空高速截击机控制台
组装歼-8高空高速截击机武器
======================================
组装歼-7前线机控制台
组装歼-7前线机机身
组装歼-7前线机引擎
组装歼-7前线机武器

以上就是通过提供的顺序来完成最终的组装,但是观察上面的main方法中的代码,提供了具体的组装命令之后,都是通过new来创建实例,并且接受组装顺序,由于两个具体的飞机都继承自Airplane,这里对其接受操作命令和返回实例做一个抽象封装,并由具体的类来实现:

public class Builder_02 {

    //飞机抽象类
    static abstract class Airplane{
        private List<String> sequences;
        //组装引擎
        protected abstract void assembleEnginee();
        //组装机身
        protected abstract void assembleBody();
        //组装控制台
        protected abstract void assembleControl();
        //组装武器
        protected abstract void assembleWeapon();

        public void finish(){
            if(null!=this.sequences && this.sequences.size()>0){
                for (String sequence : this.sequences) {
                    switch (sequence.toLowerCase()){
                        case "enginee": this.assembleEnginee();break;
                        case "body": this.assembleBody();break;
                        case "control": this.assembleControl();break;
                        case "weapon": this.assembleWeapon();break;
                        default:break;
                    }
                }
            }
        }

        public void setSequences(List<String> sequences){
            this.sequences = sequences;
        }
    }

    //歼-7前线机
    static class AnnihilatSevenAirplane extends Airplane{
        @Override
        protected void assembleEnginee() {
            System.out.println("组装歼-7前线机引擎");
        }

        @Override
        protected void assembleBody() {
            System.out.println("组装歼-7前线机机身");
        }

        @Override
        protected void assembleControl() {
            System.out.println("组装歼-7前线机控制台");
        }

        @Override
        protected void assembleWeapon() {
            System.out.println("组装歼-7前线机武器");
        }
    }
    //歼-8高空高速截击机
    static class AnnihilatEightAirplane extends Airplane{
        @Override
        protected void assembleEnginee() {
            System.out.println("组装歼-8高空高速截击机引擎");
        }

        @Override
        protected void assembleBody() {
            System.out.println("组装歼-8高空高速截击机机身");
        }

        @Override
        protected void assembleControl() {
            System.out.println("组装歼-8高空高速截击机控制台");
        }

        @Override
        protected void assembleWeapon() {
            System.out.println("组装歼-8高空高速截击机武器");
        }
    }
    //抽象建造者
    static abstract class AirplaneBuilder{
        public abstract Airplane getAirplane();

        public abstract void setSequences(List<String> sequences);
    }
    //歼-7前线机建造者
    static class AnnihilatSevenAirplaneBuilder extends AirplaneBuilder{
        private Airplane airplane = new AnnihilatSevenAirplane();
        @Override
        public Airplane getAirplane() {
            return airplane;
        }

        @Override
        public void setSequences(List<String> sequences) {
            this.airplane.setSequences(sequences);
        }
    }
    //歼-8高空高速截击机建造者
    static class AnnihilatEightAirplaneBuilder extends AirplaneBuilder{
        private Airplane airplane = new AnnihilatEightAirplane();
        @Override
        public Airplane getAirplane() {
            return airplane;
        }

        @Override
        public void setSequences(List<String> sequences) {
            this.airplane.setSequences(sequences);
        }
    }

    public static void main(String[] args) {
        //开始提供组装顺序
        List<String> sequences = new ArrayList<>();
        sequences.add("enginee");
        sequences.add("body");
        sequences.add("control");
        sequences.add("weapon");
        AnnihilatSevenAirplaneBuilder annihilatSevenAirplaneBuilder = new AnnihilatSevenAirplaneBuilder();
        annihilatSevenAirplaneBuilder.setSequences(sequences);
        annihilatSevenAirplaneBuilder.getAirplane().finish();
        System.out.println("==========================================================");
        sequences.clear();
        sequences.add("control");
        sequences.add("body");
        sequences.add("enginee");
        sequences.add("weapon");
        AnnihilatEightAirplaneBuilder annihilatEightAirplaneBuilder = new AnnihilatEightAirplaneBuilder();
        annihilatEightAirplaneBuilder.setSequences(sequences);
        annihilatEightAirplaneBuilder.getAirplane().finish();
    }
}

以上代码抽象了一个建造者类,这个抽象类负责提供具体的飞机类,已经接受组装顺序,需要具体的飞机建造者来实现。这样的改动,看起来跟之前的没多大区别,但实际上就设计而言还是好了很多,毕竟不用每次都手动new一个飞机对象,具体飞机对象的返回由对应的建造者来提供。

从上面两段代码来看,组装的顺序,以及具体的命令都是暴露在外面的,但是对客户来讲,我只需要知道顺序,具体内部命令是怎样的我并不关心,下面我们再抽象一个类来提供组装顺序,这个类由客户来调用,调用不同的方法,对应的就是不同的组装顺序,以及组装命令,看代码:

public class Builder_03 {

    //飞机抽象类
    static abstract class Airplane{
        private List<String> sequences;
        //组装引擎
        protected abstract void assembleEnginee();
        //组装机身
        protected abstract void assembleBody();
        //组装控制台
        protected abstract void assembleControl();
        //组装武器
        protected abstract void assembleWeapon();

        public void finish(){
            if(null!=this.sequences && this.sequences.size()>0){
                for (String sequence : this.sequences) {
                    switch (sequence.toLowerCase()){
                        case "enginee": this.assembleEnginee();break;
                        case "body": this.assembleBody();break;
                        case "control": this.assembleControl();break;
                        case "weapon": this.assembleWeapon();break;
                        default:break;
                    }
                }
            }
        }

        public void setSequences(List<String> sequences){
            this.sequences = sequences;
        }
    }

    //歼-7前线机
    static class AnnihilatSevenAirplane extends Airplane{
        @Override
        protected void assembleEnginee() {
            System.out.println("组装歼-7前线机引擎");
        }

        @Override
        protected void assembleBody() {
            System.out.println("组装歼-7前线机机身");
        }

        @Override
        protected void assembleControl() {
            System.out.println("组装歼-7前线机控制台");
        }

        @Override
        protected void assembleWeapon() {
            System.out.println("组装歼-7前线机武器");
        }
    }
    //歼-8高空高速截击机
    static class AnnihilatEightAirplane extends Airplane{
        @Override
        protected void assembleEnginee() {
            System.out.println("组装歼-8高空高速截击机引擎");
        }

        @Override
        protected void assembleBody() {
            System.out.println("组装歼-8高空高速截击机机身");
        }

        @Override
        protected void assembleControl() {
            System.out.println("组装歼-8高空高速截击机控制台");
        }

        @Override
        protected void assembleWeapon() {
            System.out.println("组装歼-8高空高速截击机武器");
        }
    }
    //抽象建造者
    static abstract class AirplaneBuilder{
        public abstract Airplane getAirplane();

        public abstract void setSequences(List<String> sequences);
    }
    //歼-7前线机建造者
    static class AnnihilatSevenAirplaneBuilder extends AirplaneBuilder{
        private Airplane airplane = new AnnihilatSevenAirplane();
        @Override
        public Airplane getAirplane() {
            return airplane;
        }

        @Override
        public void setSequences(List<String> sequences) {
            this.airplane.setSequences(sequences);
        }
    }
    //歼-8高空高速截击机建造者
    static class AnnihilatEightAirplaneBuilder extends AirplaneBuilder{
        private Airplane airplane = new AnnihilatEightAirplane();
        @Override
        public Airplane getAirplane() {
            return airplane;
        }

        @Override
        public void setSequences(List<String> sequences) {
            this.airplane.setSequences(sequences);
        }
    }
    //导演类,封装不同飞机型号的组装顺序
    static class Director{
        private List<String> sequences = new ArrayList<>();
        private Airplane annihilatSevenAirplane = new AnnihilatSevenAirplane();
        private Airplane annihilatEightAirplane = new AnnihilatEightAirplane();

        public Airplane getABAnnihilatSevenAirplane(){
            this.sequences.clear();
            sequences.add("enginee");
            sequences.add("body");
            this.annihilatSevenAirplane.setSequences(sequences);
            return annihilatSevenAirplane;
        }

        public Airplane getCDAnnihilatSevenAirplane(){
            this.sequences.clear();
            sequences.add("control");
            sequences.add("weapon");
            this.annihilatSevenAirplane.setSequences(sequences);
            return annihilatSevenAirplane;
        }

        public Airplane getACBDAnnihilatEightAirplane(){
            this.sequences.clear();
            sequences.add("enginee");
            sequences.add("control");
            sequences.add("body");
            sequences.add("weapon");
            this.annihilatEightAirplane.setSequences(sequences);
            return annihilatEightAirplane;
        }

    }

    public static void main(String[] args) {
        Director director = new Director();

        director.getABAnnihilatSevenAirplane().finish();

        System.out.println("==========================================================");

        director.getACBDAnnihilatEightAirplane().finish();
    }
}

以上代码添加了一个Director类,里面仅仅封装了符合客户组装顺序、命令的逻辑,并返回对应的具体飞机类,所以可以将这个类看做命令提供者,客户想指定哪种顺序组装,制度要调用对应的方法,返回对应的飞机类,然后调用finish()方法即可。
如果后续有新的顺序,只需要在这个类里面继续添加新的方法就可以了,其他的类并不需要进行修改。

以上就是建造者模式要做的事情,经过上面一步一步的修改,对建造者模式要做什么大致有一个了解。下面来看看官方的建造者模式的定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

这里面提高了构建过程,也就是我们Airplane类里面封装的finish()方法,这里面就是一个构建过程,只是如何构建是通过外部提供的命令执行顺序来构建的(也就印证了,同样的构建过程可以创建不同的表示)。

总结:

所以建造者模式,跟工厂方法和抽象工厂最大的区别在于:工厂方法和抽象方法主要在于创建对象;而建造者主要在于构建的顺序。

实际应用

参考:构建elasticsearch的restfull查询语句的方式。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值