本文目录
一、建造者模式介绍
1.1 什么是构建者模式
创建者模式又叫建造者模式,是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。创建者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加以抽象,通过子类继承或者重载的方式,动态的创建具有复合属性的对象。
1.2 适用场景
隔离复杂对象的创建和使用,相同的方法,不同执行顺序,产生不同事件结果多个部件都可以装配到一个对象中,但产生的运行结果不相同产品类非常复杂或者产品类因为调用顺序不同而产生不同作用初始化一个对象时,参数过多,或者很多参数具有默认值。
Builder模式不适合创建差异性很大的产品类产品内部变化复杂,会导致需要定义很多具体建造者类实现变化,增加项目中类的数量,增加系统的理解难度和运行成本需要生成的产品对象有复杂的内部结构,这些产品对象具备共性;
1.3 主要作用
在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
用户只需要给出指定复杂对象的类型和内容;建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)
1.4 解决的问题
方便用户创建复杂的对象(不需要知道实现过程)代码复用性 & 封装性(将对象构建过程和细节进行封装 & 复用)
例子:造汽车 & 买汽车。
工厂(建造者模式):负责制造汽车(组装过>程和细节在工厂内)
汽车购买者(用户):你只需要说出你需要的>型号(对象的类型和内容),然后直接购买就可>>以使用了(不需要知道汽车是怎么组装的(车轮、车门、>发动机、方向盘等等))
二、建造者模式实现
所有设计模式的代码实现例子都可在码云上查看哦,感兴趣的可以查看哈,码云地址:https://gitee.com/no8g/java-design-patterns
2.1 类图
增加了 Director 类,这个类是做了层封装,类中的方法说明如下:
A 型号的奔驰车辆模型是只有启动(start)、停止(stop)方法,其他的引擎声音、喇叭都没有;
B 型号的奔驰车是先发动引擎(engine boom),然后启动(star),再然后停车(stop),没有喇叭;
C 型号的宝马车是先喇叭叫一下(alarm),然后(start),再然后是停车(stop),引擎不轰鸣;
D 型号的宝马车就一个启动(start),然后一路跑到黑,永动机,没有停止方法,没有喇叭,没有引擎轰鸣;
E 型号、F 型号…等等,可以有很多,启动(start)、停止(stop)、喇叭(alarm)、引擎轰鸣(engine boom)
这四个方法在这个类中可以随意的自由组合,有几种呢?好像是排列组合,这个不会算,高中数学没学好,反正有很多种了,这里都可以实现
2.2 代码实现
package com.iot.practice.designpattern.builder.builderpattern;
/**
* <p>Client 此类用于:</p>
* <p>@author:hujm</p>
* <p>@date:2021年02月07日 10:51</p>
* <p>@remark:这里是牛叉公司的天下,他要啥我们给啥</p>
*/
public class Client {
public static void main(String[] args) {
BuilderDirector builderDirector = new BuilderDirector();
for (int i = 0; i < 10; i++) {
builderDirector.getBenzAModel().run();
}
for (int i = 0; i < 10; i++) {
builderDirector.getBenzBModel().run();
}
for (int i = 0; i < 10; i++) {
builderDirector.getBMWCModel().run();
}
for (int i = 0; i < 10; i++) {
builderDirector.getBMWDModel().run();
}
}
}
package com.iot.practice.designpattern.builder.builderpattern;
import com.iot.practice.designpattern.builder.BMWModel;
import com.iot.practice.designpattern.builder.BenzModel;
import java.util.ArrayList;
import java.util.List;
/**
* <p>BuilderPatternClient 此类用于:</p>
* <p>@author:hujm</p>
* <p>@date:2021年02月07日 9:56</p>
* <p>@remark:</p>
*/
public class BuilderPatternClient {
public static void main(String[] args) {
// 客户告诉牛叉公司,我要这样一个模型,然后牛叉公司就告诉我老大,说要这样一个模型,这样一个顺序,然后我就来制造
List<String> sequenceList = new ArrayList<>();
// 客户要求,run的时候时候先发动引擎
sequenceList.add("engine boom");
// 启动起来
sequenceList.add("start");
// 开了一段就停下来
sequenceList.add("stop");
// 要一个奔驰车:
BenzBuilder benzBuilder = new BenzBuilder();
// 把顺序给这个builder类,制造出这样一个车出来
benzBuilder.setSequence(sequenceList);
// 制造出一个奔驰车
BenzModel benzModel = (BenzModel) benzBuilder.getCarModel();
// 奔驰车跑一下看看
benzModel.run();
// 按照同样的顺序,我再要一个宝马
BMWBuilder bmwBuilder = new BMWBuilder();
bmwBuilder.setSequence(sequenceList);
BMWModel bmwModel = (BMWModel) bmwBuilder.getCarModel();
bmwModel.run();
}
}
package com.iot.practice.designpattern.builder.builderpattern;
import com.iot.practice.designpattern.builder.CarModel;
import java.util.List;
/**
* <p>CarBuilder 此类用于:</p>
* <p>@author:hujm</p>
* <p>@date:2021年02月07日 9:40</p>
* <p>@remark:要什么顺序的车,你说,我给建造出来</p>
*/
public abstract class CarBuilder {
/**
* 建造一个模型,你要给我一个顺序要,就是组装顺序
*
* @param sequence 组装顺序
*/
public abstract void setSequence(List<String> sequence);
/**
* 设置完毕顺序后,就可以直接拿到这个车辆模型
*
* @return 车辆模型
*/
public abstract CarModel getCarModel();
}
package com.iot.practice.designpattern.builder.builderpattern;
import com.iot.practice.designpattern.builder.BMWModel;
import com.iot.practice.designpattern.builder.BenzModel;
import java.util.ArrayList;
import java.util.List;
/**
* <p>BuilderDirector 此类用于:</p>
* <p>@author:hujm</p>
* <p>@date:2021年02月07日 10:12</p>
* <p>@remark:导演安排顺序,生产车辆模型</p>
*/
public class BuilderDirector {
private List<String> sequenceList = new ArrayList<>();
private BenzBuilder benzBuilder = new BenzBuilder();
private BMWBuilder bmwBuilder = new BMWBuilder();
/**
* A类型的奔驰车模型,先start,然后stop,其他什么引擎了,喇叭一概没有
*
* @return A类型的奔驰车模型
*/
public BenzModel getBenzAModel() {
// 清理场景,这里是一些初级程序员不注意的地方
this.sequenceList.clear();
// 这只BenzAModel的执行顺序
this.sequenceList.add("start");
this.sequenceList.add("stop");
this.benzBuilder.setSequence(sequenceList);
return (BenzModel) this.benzBuilder.getCarModel();
}
/**
* B型号的奔驰车模型,是先发动引擎,然后启动,然后停止,没有喇叭
*
* @return B型号的奔驰车模型
*/
public BenzModel getBenzBModel() {
// 清理场景,这里是一些初级程序员不注意的地方
this.sequenceList.clear();
// 这只BenzBModel的执行顺序
this.sequenceList.add("engine boom");
this.sequenceList.add("start");
this.sequenceList.add("stop");
this.benzBuilder.setSequence(sequenceList);
return (BenzModel) this.benzBuilder.getCarModel();
}
/**
* C型号的宝马车是先按下喇叭(炫耀嘛),然后启动,然后停止
*
* @return C型号的宝马车
*/
public BMWModel getBMWCModel() {
this.sequenceList.clear();
this.sequenceList.add("alarm");
this.sequenceList.add("start");
this.sequenceList.add("stop");
this.bmwBuilder.setSequence(sequenceList);
return (BMWModel) this.bmwBuilder.getCarModel();
}
/**
* D类型的宝马车只有一个功能,就是跑,启动起来就跑,永远不停止,牛叉
*
* @return D型号的宝马车
*/
public BMWModel getBMWDModel() {
this.sequenceList.clear();
this.sequenceList.add("start");
this.bmwBuilder.setSequence(sequenceList);
return (BMWModel) this.bmwBuilder.getCarModel();
}
/**
* 这里还可以有很多方法,你可以先停止,然后再启动,或者一直停着不动,静态的嘛
* 导演类嘛,按照什么顺序是导演说了算
*/
}
package com.iot.practice.designpattern.builder.builderpattern;
import com.iot.practice.designpattern.builder.BMWModel;
import com.iot.practice.designpattern.builder.CarModel;
import java.util.List;
/**
* <p>BMWBuilder 此类用于:</p>
* <p>@author:hujm</p>
* <p>@date:2021年02月07日 9:53</p>
* <p>@remark:给定一个顺序,返回一个宝马车</p>
*/
public class BMWBuilder extends CarBuilder{
private BMWModel bmwModel = new BMWModel();
@Override
public void setSequence(List<String> sequence) {
this.bmwModel.setSequenceList(sequence);
}
@Override
public CarModel getCarModel() {
return this.bmwModel;
}
}
package com.iot.practice.designpattern.builder.builderpattern;
import com.iot.practice.designpattern.builder.BenzModel;
import com.iot.practice.designpattern.builder.CarModel;
import java.util.List;
/**
* <p>BenzBuilder 此类用于:</p>
* <p>@author:hujm</p>
* <p>@date:2021年02月07日 9:49</p>
* <p>@remark:各种设施都给了,我们按照一定的顺序制造一个奔驰车</p>
*/
public class BenzBuilder extends CarBuilder{
private BenzModel benzModel = new BenzModel();
@Override
public void setSequence(List<String> sequence) {
this.benzModel.setSequenceList(sequence);
}
@Override
public CarModel getCarModel() {
return this.benzModel;
}
}
2.3 角色分析
整个程序编写完毕,而且简洁明了,这就是建造者模式,中间有几个角色需要说明一下:
Client 就是牛叉公司,这个到具体的应用中就是其他的模块或者页面;
CarModel 以及两个实现类 BenzModel 和 BMWModel 叫做产品类(Product Class),这个产品类实现了模板方法模式,也就是有模板方法和基本方法,这个参考上一节的模板方法模式;
CarBuilder 以及两个实现类 BenzBuilder 和 BMWBuilder 叫做建造者(Builder Class),在上面的那个例子中就是我和我的团队,负责建造 Benz 和 BMW 车模,按照指定的顺序;
Director 类叫做导演类(Director Class),负责安排已有模块的顺序,然后告诉 Builder 开始建造,在上面的例子中就是我们的老大,Client 找到老大,说我要这个,这个,那个类型的车辆模型,然后老大就把命令传递给我,我和我的团队就开始拼命的建造,于是一个项目建设完毕了。
这个建造者模式和工厂模式是非常相似,但是记住一点你就可以游刃有余的使用了:
建造者模式最主要功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了;
而工厂方法则重点是创建,你要什么对象我创造一个对象出来,组装顺序则不是他关心的。
完结!