设计模式11-Builder

本文最后更新于:3 years ago

建造者模式

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

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

如果想了解建造者模式的具体的介绍,菜鸟教程介绍得比较详细↓
菜鸟教程-建造者模式

结构图


意图

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

优缺点

优点:

1、建造者独立,易扩展。
2、便于控制细节风险。

缺点:

1、产品必须有共同点,范围有限制。
2、如内部变化复杂,会有很多的建造类。

使用场景

1、需要生成的对象具有复杂的内部结构。
2、需要生成的对象内部属性本身相互依赖。

实现代码

建造者模式也不是很难,可以说都不用去记忆的。但是介绍起来还是有一些复杂的,这里较详细介绍一下。

建造者模式在我们开发过程中,其实主要用于解决当你创建一个对象,需要往构造方法中添加很多参数时用到的。

这里我们模拟一个场景,你要构造一片森林,森林里有三个对象,动物,植物和山(可以有很多东西,你可以无限想象,模拟的就是创建森林对象时需要传入很多参数的情况)。
每个对象都有各自的高度和重量。

三个可能不是很多,但如果成百上千呢?都需要你传入相应的高度和重量,麻烦了…

这个时候,你就可以想到建造者模式。

分析一下,首先,创建一个Forest类,这个类中,有 Plant, Animal, Mountain三种对象。

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
public class Forest {
Plant plant;
Animal animal;
Mountain mountain;

}

class Plant{
int height,weight;

public Plant(int height, int weight) {
this.height = height;
this.weight = weight;
}
}

class Animal{
int height,weight;

public Animal(int height, int weight) {
this.height = height;
this.weight = weight;
}
}

class Mountain{
int height,weight;

public Mountain(int height, int weight) {
this.height = height;
this.weight = weight;
}
}

接着定义一个ForestBuilder接口,定义四个方法,分别是用来构建Plant,Animal,Mountain和Forest

1
2
3
4
5
6
public interface ForestBuilder {
ForestBuilder buildPlant(int height, int weight);
ForestBuilder buildAnimal(int height, int weight);
ForestBuilder buildMountain(int height, int weight);
Forest build();
}

这里为什么 buildPlant buildAnimal buildMountain 返回类型是 ForestBuilder
我后面会解释

接着,我们创建ComplexForestBuilder类来实现 ForestBuilder 接口

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
public class ComplexForestBuilder implements ForestBuilder{
Forest forest = new Forest();

@Override
public ForestBuilder buildPlant(int height, int weight) {
forest.plant = new Plant(height, weight);
return this;
}

@Override
public ForestBuilder buildAnimal(int height, int weight) {
forest.animal = new Animal(height,weight);
return this;
}

@Override
public ForestBuilder buildMountain(int height, int weight) {
forest.mountain = new Mountain(height, weight);
return this;
}

@Override
public Forest build() {
return forest;
}
}

到了这里其实还是没有看出来建造者模式体现在哪里,别急

我们编写Mian函数来实现这个类:

1
2
3
4
5
6
public class Main {
public static void main(String[] args) {
ForestBuilder builder = new ComplexForestBuilder();
Forest forest = builder.buildAnimal(50, 50).buildPlant(100, 100).buildMountain(200, 200).build();
}
}

乍一看是不是有点不太清楚,但有点熟悉

先解决为什么 buildPlant buildAnimal buildMountain 返回类型是 ForestBuilder
这里看了

1
Forest forest = builder.buildAnimal(50, 50).buildPlant(100, 100).buildMountain(200, 200).build();

是不是有一点想法,这就是链式编程(我在责任链模式那一块也用到了链式编程)
buildAnimal() 返回的是 ForestBuilder 时,可以继续调用 buildPlant() 然后继续下去…

但是和我直接往里面传入对象有什么区别吗?

1
2
3
4
5
6
public class Main {
public static void main(String[] args) {
ForestBuilder builder = new ComplexForestBuilder();
Forest forest = builder.buildPlant(100, 100).buildMountain(200, 200).build();
}
}

现在是不是就有点懂了,我们可以任意传入我们想要的传入的值,而一些我们不想传入的参数,就可以避免了。
拿上面的例子来讲,森林中有动物,植物,山…参数可以很多,但我想要的只是改变森林中的动物和植物,其他的我都用默认的。
于是我只要调用方法,来 builder 我们自己想要的 animal 和 plant 就可以了,是不是就可以避免创建时传入很多不必要的参数了
(当然,你要非说我要将所有对象的不同组合构造参数都写出来…那我没话说了)

是不是很神奇,但是,不是经常用到的设计模式,不需要刻意去记忆,用到的时候能想到就行了。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!