大数据知识体系
首页
数据结构与算法
  • JVM
  • Java
  • Scala
  • Python
设计模式
  • MySQL
  • Redis
  • HDFS
  • HBase
  • ClickHouse
  • ElasticSearch
  • Iceberg
  • Hudi
  • Spark
  • Flink
  • Hive
  • Yarn
  • Zookeeper
  • Maven
  • Git
  • 数据仓库
  • 用户画像
  • 指标体系
数据治理
关于
首页
数据结构与算法
  • JVM
  • Java
  • Scala
  • Python
设计模式
  • MySQL
  • Redis
  • HDFS
  • HBase
  • ClickHouse
  • ElasticSearch
  • Iceberg
  • Hudi
  • Spark
  • Flink
  • Hive
  • Yarn
  • Zookeeper
  • Maven
  • Git
  • 数据仓库
  • 用户画像
  • 指标体系
数据治理
关于
  • 设计模式概述
  • 创建型模式

    • 单例模式
    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式
    • 建造者模式
      • 一、概述
        • 1.1 解决了什么问题
        • 1.2 解决方案
      • 二、实现方式
        • 2.1 经典版实现
        • 2.2 简化版实现
      • 三、源码中的应用
    • 原型模式
  • 结构型模式

    • 适配器模式
    • 装饰器模式
    • 代理模式
    • 外观模式
    • 桥接模式
    • 组合模式
    • 享元模式
  • 行为型模式

    • 策略模式
    • 模板方法模式
    • 观察者模式
    • 迭代器模式
    • 责任链模式
    • 命令模式
    • 备忘录模式
    • 状态模式
    • 访问者模式
    • 中介者模式
    • 解释器模式
  • 设计模式
  • 创建型模式
Will
2022-03-29
目录

建造者模式

# 一、概述

建造者(Builder)模式也称作生成器模式,它能够将复杂对象的构造过程抽象出来分步进行,使得通过抽象过程的不同方法可以构造不同属性的对象。

# 1.1 解决了什么问题

大家都知道传统燃油车的三大件:发动机、变速箱和地盘悬架。也就说说对于一辆燃油车而言,这三个是必须存在的。但是一些其它的配置(如:变道辅助、倒车雷达、ACC 自适应巡航、电尾门等)可能会由于品牌、车型、价位等可有可无,哪怕是同一品牌的同一款车,也可能会根据客户需求进行选装。

如果有一个描述汽车的抽象类:

class Automobile {

    /**
     * 发动机
     */
    private String engine;

    /**
     * 变速箱
     */
    private String gearbox;

    /**
     * 底盘悬架
     */
    private String chassisSuspension;

    /**
     * ACC 自适应巡航
     */
    private String acc;

    /**
     * 倒车雷达
     */
    private String reversingRadar;

    /**
     * 电动尾门
     */
    private String electricTailgate;

    /**
     * 变道辅助
     */
    private String laneChangeAssist;

    public Automobile(String engine, String gearbox, String chassisSuspension, String acc, String reversingRadar, String electricTailgate, String laneChangeAssist) {
        this.engine = engine;
        this.gearbox = gearbox;
        this.chassisSuspension = chassisSuspension;
        this.acc = acc;
        this.reversingRadar = reversingRadar;
        this.electricTailgate = electricTailgate;
        this.laneChangeAssist = laneChangeAssist;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

那么如果要创建不同配置的车型,则代码可能是这样的:

new Automobile("2.0T", "双离合", "非独立悬架", null, null, "有电尾门", null);
new Automobile("2.0T", "双离合", "非独立悬架", null, "有倒车雷达", null, "有并线辅助");
new Automobile("2.0T", "双离合", "非独立悬架", "ACC", null, null, "有并线辅助");
1
2
3

这种方式其实是非常不友好的,如果参数再多一点,那么按照位置从左往右对齐的话很可能会出错,而且看起来也很丑。

# 1.2 解决方案

对于上面这种情况,建造者模式的思想是将构造对象的过程分成多个步骤执行,在每个步骤中完成一项配置的添加,这样就达到了按需生产的需求,也不会应为构造参数过多而出现配置错误的情况。比如:第一步先构造一个空壳子、接下里安装底盘、再安装发动机、再安装变速箱、再安装电尾门......

一般来说,当一个类的参数较多且有些参数可以按需出现的时候,就可以考虑使用建造者模式。

# 二、实现方式

# 2.1 经典版实现

在经典建造者模式中有四个角色:

  1. 产品:即一个具体的产品对象。
  2. 抽象建造者:指定创建一个产品对象各个部件的接口。
  3. 具体建造者:用于具体实现各个部件的构建和装配。
  4. 指挥者:定义调用构造步骤的顺序,负责控制对象对象的生产过程。

第一步,构建 Product 角色,即最终需要产出的 Automobile 类:

class Automobile {
    /**
     * 发动机
     */
    private String engine;

    /**
     * 变速箱
     */
    private String gearbox;

    /**
     * 底盘悬架
     */
    private String chassisSuspension;

    /**
     * ACC 自适应巡航
     */
    private String acc;

    /**
     * 倒车雷达
     */
    private String reversingRadar;

    /**
     * 电动尾门
     */
    private String electricTailgate;

    /**
     * 变道辅助
     */
    private String laneChangeAssist;

    public Automobile(String engine, String gearbox, String chassisSuspension) {
        this.engine = engine;
        this.gearbox = gearbox;
        this.chassisSuspension = chassisSuspension;
    }

    public void setEngine(String engine) {
        this.engine = engine;
    }

    public void setGearbox(String gearbox) {
        this.gearbox = gearbox;
    }

    public void setChassisSuspension(String chassisSuspension) {
        this.chassisSuspension = chassisSuspension;
    }

    public void setAcc(String acc) {
        this.acc = acc;
    }

    public void setReversingRadar(String reversingRadar) {
        this.reversingRadar = reversingRadar;
    }

    public void setElectricTailgate(String electricTailgate) {
        this.electricTailgate = electricTailgate;
    }

    public void setLaneChangeAssist(String laneChangeAssist) {
        this.laneChangeAssist = laneChangeAssist;
    }

    @Override
    public String toString() {
        return "Automobile{" +
                "engine='" + engine + '\'' +
                ", gearbox='" + gearbox + '\'' +
                ", chassisSuspension='" + chassisSuspension + '\'' +
                ", acc='" + acc + '\'' +
                ", reversingRadar='" + reversingRadar + '\'' +
                ", electricTailgate='" + electricTailgate + '\'' +
                ", laneChangeAssist='" + laneChangeAssist + '\'' +
                '}';
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

第二步,构建抽象建造者 Builder,在 Builder 中指定创建 Automobile 类的接口:

interface Builder {
    void setAcc(String acc);
    void setReversingRadar(String reversingRadar);
    void setElectricTailgate(String electricTailgate);
    void setLaneChangeAssist(String laneChangeAssist);
}
1
2
3
4
5
6

第三步,构建具体的建造者,实现各个部件的构建和装配:

class AutomobileBuilder implements Builder {

    private Automobile automobile;

    public AutomobileBuilder(String engine, String gearbox, String chassisSuspension) {
        automobile = new Automobile(engine, gearbox, chassisSuspension);
    }

    @Override
    public void setAcc(String acc) {
        automobile.setAcc(acc);
    }

    @Override
    public void setReversingRadar(String reversingRadar) {
        automobile.setReversingRadar(reversingRadar);
    }

    @Override
    public void setElectricTailgate(String electricTailgate) {
        automobile.setElectricTailgate(electricTailgate);
    }

    @Override
    public void setLaneChangeAssist(String laneChangeAssist) {
        automobile.setLaneChangeAssist(laneChangeAssist);
    }

    public Automobile build() {
        return automobile;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

第四步,创建指挥者,根据不同生产需求组装不同配置的车型:

class AutomobileDirector {
    public void constructSportsCar(Builder builder) {
        builder.setAcc("有ACC");
        builder.setElectricTailgate("有电尾门");
        builder.setLaneChangeAssist("有并线辅助");
        builder.setReversingRadar("有倒车雷达");
    }

    public void constructCityCar(Builder builder) {
        builder.setAcc("有ACC");
        builder.setReversingRadar("有倒车雷达");
    }

    public void constructSUV(Builder builder) {
        builder.setAcc("有ACC");
        builder.setElectricTailgate("有电尾门");
        builder.setLaneChangeAssist("有并线辅助");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

最后看下使用案例:

public class BuilderTest {
    public static void main(String[] args) {
        // 指挥者
        AutomobileDirector director = new AutomobileDirector();
        // 具体建造者
        AutomobileBuilder builder1 = new AutomobileBuilder("2.0T", "双离合", "独立悬架");
        AutomobileBuilder builder2 = new AutomobileBuilder("2.0T", "双离合", "独立悬架");
        AutomobileBuilder builder3 = new AutomobileBuilder("2.0T", "双离合", "独立悬架");

        // 建造第一种车型
        director.constructCityCar(builder1);
        Automobile cityCar = builder1.build();
        System.out.println(cityCar);

        // 建造第二种车型
        director.constructSportsCar(builder2);
        Automobile sportsCar = builder2.build();
        System.out.println(sportsCar);

        // 建造第三种车型
        director.constructSUV(builder3);
        Automobile suv = builder3.build();
        System.out.println(suv);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Automobile{engine='2.0T', gearbox='双离合', chassisSuspension='独立悬架', acc='有ACC', reversingRadar='有倒车雷达', electricTailgate='null', laneChangeAssist='null'}
Automobile{engine='2.0T', gearbox='双离合', chassisSuspension='独立悬架', acc='有ACC', reversingRadar='有倒车雷达', electricTailgate='有电尾门', laneChangeAssist='有并线辅助'}
Automobile{engine='2.0T', gearbox='双离合', chassisSuspension='独立悬架', acc='有ACC', reversingRadar='null', electricTailgate='有电尾门', laneChangeAssist='有并线辅助'}
1
2
3

# 2.2 简化版实现

建造者模式的经典实现方法相对来说是比较繁琐的,反而通过内部类实现的简化版的见得比较多。

public class SimpleBuilderTest {
    public static void main(String[] args) {
        Automobile automobile = new Automobile.Builder("2.0T", "双离合", "独立悬架")
                .setAcc("有ACC")
                .setElectricTailgate("有电尾门")
                .setReversingRadar("有倒车雷达")
                .build();

        System.out.println(automobile);
    }
}

class Automobile {
    private String engine;
    private String gearbox;
    private String chassisSuspension;
    private String acc;
    private String reversingRadar;
    private String electricTailgate;
    private String laneChangeAssist;

    private Automobile(Builder builder) {
        this.engine = builder.engine;
        this.gearbox = builder.gearbox;
        this.chassisSuspension = builder.chassisSuspension;
        this.acc = builder.acc;
        this.reversingRadar = builder.reversingRadar;
        this.electricTailgate = builder.electricTailgate;
        this.laneChangeAssist = builder.laneChangeAssist;
    }

    @Override
    public String toString() {
        return "Automobile{" +
                "engine='" + engine + '\'' +
                ", gearbox='" + gearbox + '\'' +
                ", chassisSuspension='" + chassisSuspension + '\'' +
                ", acc='" + acc + '\'' +
                ", reversingRadar='" + reversingRadar + '\'' +
                ", electricTailgate='" + electricTailgate + '\'' +
                ", laneChangeAssist='" + laneChangeAssist + '\'' +
                '}';
    }

    public static class Builder {
        private String engine;
        private String gearbox;
        private String chassisSuspension;
        private String acc;
        private String reversingRadar;
        private String electricTailgate;
        private String laneChangeAssist;

        public Builder(String engine, String gearbox, String chassisSuspension) {
            this.engine = engine;
            this.gearbox = gearbox;
            this.chassisSuspension = chassisSuspension;
        }

        public Builder setAcc(String acc) {
            this.acc = acc;
            return this;
        }

        public Builder setReversingRadar(String reversingRadar) {
            this.reversingRadar = reversingRadar;
            return this;
        }

        public Builder setElectricTailgate(String electricTailgate) {
            this.electricTailgate = electricTailgate;
            return this;
        }

        public Builder setLaneChangeAssist(String laneChangeAssist) {
            this.laneChangeAssist = laneChangeAssist;
            return this;
        }

        public Automobile build() {
            return new Automobile(this);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

# 三、源码中的应用

  1. java.lang.StringBuilder#append() (unsynchronized)
  2. java.lang.StringBuffer#append() (synchronized)
上次更新: 2023/11/01, 03:11:44

← 抽象工厂模式 原型模式→

Theme by Vdoing | Copyright © 2022-2023 Will 蜀ICP备2022002285号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式