设计模式(五)—建造者模式
最后更新于:2022-04-01 16:26:02
**英文名称**: Builder Pattern又叫做生成器模式
**定义**:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
## 建造者的一般模式
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_57553408da4db.jpg)
Product产品类:实现了模板方法模式,也就是有模板方法和基本方法。
Builder类抽象建造者,规范产品的组件,一般是由子类实现 ConcreteBuilder具体建造者,实现抽象类类定义的 所有方法,并返回一个组建好的对象。
Directoer 导演类负责安排已有的模块的顺序,然后告诉Builder开始建造。
该例子只是为了说明 建造者模式的一般模式,并没有实际的开发场景,因此,在实际项目开发环境中,应该灵活应用建造者模式。
~~~
public class BuilderPattern {
public static void main(String[] args) {
MyDirector director = new MyDirector();
Product p = director.getProduct();
p.mothod();
}
}
class Product {
//该类可以引入模板模式,也可以为普通的类。
protected void mothod(){
System.out.println("我是产品类中的方法....");
}
}
abstract class ProductBuilder{
//该类为抽象的建造者类。具体实现方法是由子类来完成的。
public abstract Product getProduct();
}
class AProductBuilder extends ProductBuilder{
//该类是建造者抽像类的具体实现类。创建出需要的实例。
private Product p = new Product();
@Override
public Product getProduct() {
// TODO Auto-generated method stub
return this.p;
}
}
class MyDirector{
//该类是指挥者类,主要用与高速创建者类需要创建的对象。
private AProductBuilder apBuilder = new AProductBuilder();
public Product getProduct(){
return this.apBuilder.getProduct();
}
}
~~~
**一个例子**:
建造一个生产汽车的模板,具有start(),stop(),alarm(),engineBoom(),run()等方法。
但是现在的需求是,根据用户的要求来生产不同类型的车模。例如,宝马车的模型,按照用户的需求来启动宝马车。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_57553408f2d97.jpg)
~~~
public class BuilderTest {
public static void main(String[] args) {
//使用指挥者,直接构建模板类型的实例
Director director = new Director();
//获取奔驰车实例
BenzModel benz = (BenzModel) director.getA_BenzCarModel();
benz.run();
}
}
class Director{
private ArrayList<String> sequence = new ArrayList<String>();
private BenzBuilder benzBuilder = new BenzBuilder();
private BMWBuilder bmwBuilder = new BMWBuilder();
/**
* 宝马车A的模型
* @return 宝马车的实例
*/
public Model getA_BMWCarModel(){
//先将集合中的数据清空
this.sequence.clear();
//为用户定义宝马车的启动方式
sequence.add("start");
sequence.add("alarm");
sequence.add("stop");
this.bmwBuilder.setSequence(sequence);
return this.bmwBuilder.getModel();
}
/**
* 宝马车B的模型
* @return 宝马车B的实例
*/
public Model getB_BMWCarModel(){
//先将集合中的数据清空
this.sequence.clear();
//为用户定义宝马车的启动方式
sequence.add("start");
sequence.add("alarm");
sequence.add("engine boom");
sequence.add("stop");
this.bmwBuilder.setSequence(sequence);
return this.bmwBuilder.getModel();
}
/**
* 奔驰车A的模型
* @return 奔驰车的实例
*/
public Model getA_BenzCarModel(){
//先将集合中的数据清空
this.sequence.clear();
//为用户定义宝马车的启动方式
sequence.add("start");
sequence.add("alarm");
sequence.add("engine boom");
sequence.add("stop");
this.benzBuilder.setSequence(sequence);
return this.benzBuilder.getModel();
}
/**
* 奔驰车B的模型
* @return 奔驰车的实例
*/
public Model getB_BenzCarModel(){
//先将集合中的数据清空
this.sequence.clear();
//为用户定义宝马车的启动方式
sequence.add("start");
sequence.add("alarm");
sequence.add("engine boom");
sequence.add("stop");
this.benzBuilder.setSequence(sequence);
return this.benzBuilder.getModel();
}
}
abstract class Model{
ArrayList<String> sequence = new ArrayList<String>();
//车辆启动
protected abstract void start();
//车辆停止
protected abstract void stop();
//车辆鸣笛
protected abstract void alarm();
//车辆发动机轰鸣
protected abstract void engineBoom();
protected void run(){
Iterator<String> it = sequence.iterator();
while(it.hasNext()){
String str = it.next();
if(str.equalsIgnoreCase("engine boom")){
this.engineBoom();
}else if(str.equalsIgnoreCase("start")){
this.start();
}else if(str.equalsIgnoreCase("alarm")){
this.alarm();
}else{
this.stop();
}
}
}
protected void setSequence(ArrayList<String> sequence){
this.sequence = sequence;
}
}
class BMWModel extends Model{
@Override
protected void start() {
System.out.println("宝马车启动...");
}
@Override
protected void stop() {
System.out.println("宝马车停止...");
}
@Override
protected void alarm() {
System.out.println("宝马车开始鸣笛...");
}
@Override
protected void engineBoom() {
System.out.println("宝马车发动机轰鸣...");
}
}
class BenzModel extends Model{
@Override
protected void start() {
System.out.println("奔驰启动...");
}
@Override
protected void stop() {
System.out.println("奔驰停止...");
}
@Override
protected void alarm() {
System.out.println("奔驰开始鸣笛...");
}
@Override
protected void engineBoom() {
System.out.println("奔驰发动机轰鸣...");
}
}
abstract class CarBuilder{
//用户自定义车辆启动方式
protected abstract void setSequence(ArrayList<String> sequence);
//返回Model类及其子类的实例
protected abstract Model getModel();
}
class BenzBuilder extends CarBuilder{
private Model benz = new BenzModel();
@Override
protected void setSequence(ArrayList<String> sequence) {
this.benz.setSequence(sequence);
}
@Override
protected Model getModel() {
// TODO Auto-generated method stub
return this.benz;
}
}
class BMWBuilder extends CarBuilder{
private Model bmw = new BMWModel();
@Override
protected void setSequence(ArrayList<String> sequence) {
// TODO Auto-generated method stub
this.bmw.setSequence(sequence);
}
@Override
protected Model getModel() {
// TODO Auto-generated method stub
return this.bmw;
}
}
~~~
**Tip:(开发中的小习惯)**
1、this调用当调用本类中的成员变量或方法时,要使用this关键字,以区分本方法中的一个变量
2、super调用,当调用父类的成员变量和方法时,使用super关键字
3、当ArrayList和HashMap如果定义成类的成员变量,那在方法中的调用一定要做一个clear的动作,以防止数据混乱
## 建造者模式使用场景
1、相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式
2、多个部件和零件,都可以装配到一个对象中,到那时产生的运行结果又不相同时,这可以使用该模式
3、产品类十分复杂,或者产品类中的调用顺序不同产生了不同的效能,使用建造者模式