本文最后更新于: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
| 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函数来实现这个类:
| 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
这里看了
| Forest forest = builder.buildAnimal(50, 50).buildPlant(100, 100).buildMountain(200, 200).build();
|
是不是有一点想法,这就是链式编程(我在责任链模式那一块也用到了链式编程)
当 buildAnimal()
返回的是 ForestBuilder
时,可以继续调用 buildPlant()
然后继续下去…
但是和我直接往里面传入对象有什么区别吗?
| 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 就可以了,是不是就可以避免创建时传入很多不必要的参数了
(当然,你要非说我要将所有对象的不同组合构造参数都写出来…那我没话说了)
是不是很神奇,但是,不是经常用到的设计模式,不需要刻意去记忆,用到的时候能想到就行了。