设计模式之建造者模式

个人理解:
建造者模式就是组装已知的方法的执行顺序,从而让一个同一个的方法的执行顺序不同,产生类的效果就不同的。
首先我们来看一下类图
在这里插入图片描述
在抽象模型CarModel中有居多的方法,start(),stop(),alam()…,实现的子类不同,方法不同的执行顺序就会有不同的结果。
例如:奔驰模型A是先有引擎声音,然后再响喇叭;奔驰模型B是先启动起来,然后再有引擎声音,需求是不同的,模型当然是不同的run方法的组装顺序是不同的。
车辆模型的抽象类

public abstract class CarModel {
//这个参数是各个基本方法执行的顺序
private ArrayList<String> sequence = new ArrayList<String>();
//模型是启动开始跑了
protected abstract void start();
//能发动,还要能停下来,那才是真本事
protected abstract void stop();
//喇叭会出声音,是滴滴叫,还是哔哔叫
protected abstract void alarm();
//引擎会轰隆隆地响,不响那是假的
protected abstract void engineBoom();
//那模型应该会跑吧,别管是人推的,还是电力驱动,总之要会跑
final public void run() {
//循环一边,谁在前,就先执行谁
for(int i=0;i<this.sequence.size();i++){
String actionName = this.sequence.get(i);
if(actionName.equalsIgnoreCase("start")){
this.start(); //启动汽车
}else if(actionName.equalsIgnoreCase("stop")){
this.stop(); //停止汽车
}else if(actionName.equalsIgnoreCase("alarm")){
this.alarm(); //喇叭开始叫了
}else if(actionName.equalsIgnoreCase("engine boom")){
//如果是engine boom关键字
this.engineBoom(); //引擎开始轰鸣
}
}
}
//把传递过来的值传递到类内
final public void setSequence(ArrayList sequence){
this.sequence = sequence;
}
}

用户可以根据自己的设定顺序来动态调整,组装出不同的模型出来。
实现过程:在子类中实现父类的基本方法,run()方法读取sequence,然后遍历sequence中的字符串,哪个字符串在先,就先执行哪个方法。
奔驰模型代码

public class BenzModel extends CarModel {
protected void alarm() {
System.out.println("奔驰车的喇叭声音是这个样子的...");
}
protected void engineBoom() {
System.out.println("奔驰车的引擎是这个声音的...");
}
protected void start() {
System.out.println("奔驰车跑起来是这个样子的...");
}
protected void stop() {
System.out.println("奔驰车应该这样停车...");
}
}

我们来写一个场景类来模拟一下该过程

public class Client {
public static void main(String[] args) {
/*
* 客户告诉XX公司,我要这样一个模型,然后XX公司就告诉我老大
* 说要这样一个模型,这样一个顺序,然后我就来制造
*/
BenzModel benz = new BenzModel();
//存放run的顺序
ArrayList<String> sequence = new ArrayList<String>();
sequence.add("engine boom"); //客户要求,run的时候先发动引擎
sequence.add("start"); //启动起来
sequence.add("stop"); //开了一段就停下来
//我们把这个顺序赋予奔驰车
benz.setSequence(sequence);
benz.run();
}
}

结果是:

在这里插入图片描述
这样的话非常爽,我们就可以通过不同的顺序,保证,奔驰车,可以由用户来决定是否执行,某个方法已经方法的执行顺序。
但是页存在了一个明显的问题,就是每个模型都有不同的执行方法的顺序,宝马和奔驰顺序就可能不一样,如果是更多呢,不止一个,N个的时候怎么办呢,
有一个办法,把这个顺序给一个类来管理,你需要啥顺序,在这个类中调用就行,这个类包含了需要的所以执行顺序。我们就称这个类是建造者,负责主要的方法顺序的管理(也可以由具体的业务逻辑管理哦,业务逻辑就是抽象的)
我们来看一下类图
在这里插入图片描述
给一个抽象汽车的组装者,需要什么类型,都是由它的子类完成

抽象汽车组装者代码

public abstract class CarBuilder {
//建造一个模型,你要给我一个顺序要求,就是组装顺序
public abstract void setSequence(ArrayList<String> sequence);
//设置完毕顺序后,就可以直接拿到这个车辆模型
public abstract CarModel getCarModel();
}

奔驰汽车的组装者

public class BenzBuilder extends CarBuilder {
private BenzModel benz = new BenzModel();
public CarModel getCarModel() {
return this.benz;
}
public void setSequence(ArrayList<String> sequence) {
this.benz.setSequence(sequence);
}
}

宝马车组装者‘

public class BMWBuilder extends CarBuilder {
private BMWModel bmw = new BMWModel();
public CarModel getCarModel() {
return this.bmw;
}
public void setSequence(ArrayList<String> sequence) {
this.bmw.setSequence(sequence);
}
}

修改后的场景类

public class Client {
public static void main(String[] args) {
/*
* 客户告诉XX公司,我要这样一个模型,然后XX公司就告诉我老大
* 说要这样一个模型,这样一个顺序,然后我就来制造
*/
//存放run的顺序
ArrayList<String> sequence = new ArrayList<String>();
sequence.add("engine boom"); //客户要求,run时候时候先发动引擎
sequence.add("start"); //启动起来
sequence.add("stop"); //开了一段就停下来
//要一个奔驰车:
BenzBuilder benzBuilder = new BenzBuilder();
//把顺序给这个builder类,制造出这样一个车出来
benzBuilder.setSequence(sequence);
//制造出一个奔驰车
BenzModel benz = (BenzModel)benzBuilder.getCarModel();
//奔驰车跑一下看看
benz.run();
}
}

我们在做项目时,经常会有一个共识:需求是无底洞,是无理性的,不可能你告诉它不增加需求就不增加,这4个过程(start、stop、alarm、engine boom)按照排列组合有很多种,××公司可以随意组合,它要什么顺序的车模我就必须生成什么顺序的车模,客户可是上帝!那我们不可能预知他们要什么顺序的模型呀,所以我们封装一下有个具体的导演,这个导演负责专门指挥每个事件的执行顺序。

在这里插入图片描述
说明一下作用
getABenzModel方法 组建出A型号的奔驰车辆模型,其过程为只有启动(start)、停止(stop)方法,其他的
引擎声音、喇叭都没有。
getBBenzModel方法
组建出B型号的奔驰车,其过程为先发动引擎(engine boom),然后启动,再然后停
车,没有喇叭。
导演的代码

public class Director {
private ArrayList<String> sequence = new ArrayList();
private BenzBuilder benzBuilder = new BenzBuilder();
private BMWBuilder bmwBuilder = new BMWBuilder();
/*
* A类型的奔驰车模型,先start,然后stop,其他什么引擎、喇叭一概没有
*/
public BenzModel getABenzModel(){
//清理场景,这里是一些初级程序员不注意的地方
this.sequence.clear();
//ABenzModel的执行顺序
this.sequence.add("start");
this.sequence.add("stop");
//按照顺序返回一个奔驰车
this.benzBuilder.setSequence(this.sequence);
return (BenzModel)this.benzBuilder.getCarModel();
}
/*
* B型号的奔驰车模型,是先发动引擎,然后启动,然后停止,没有喇叭
*/
public BenzModel getBBenzModel(){
this.sequence.clear();
this.sequence.add("engine boom");
this.sequence.add("start");
this.sequence.add("stop");
this.benzBuilder.setSequence(this.sequence);
return (BenzModel)this.benzBuilder.getCarModel();
}
/*
* C型号的宝马车是先按下喇叭(炫耀嘛),然后启动,然后停止
*/
public BMWModel getCBMWModel(){
this.sequence.clear();
this.sequence.add("alarm");
this.sequence.add("start");
this.sequence.add("stop");
this.bmwBuilder.setSequence(this.sequence);
return (BMWModel)this.bmwBuilder.getCarModel();
}
/*
* D类型的宝马车只有一个功能,就是跑,启动起来就跑,永远不停止
*/
public BMWModel getDBMWModel(){
this.sequence.clear();
this.sequence.add("start");
this.bmwBuilder.setSequence(this.sequence);
return (BMWModel)this.benzBuilder.getCarModel();
}
/*
* 这里还可以有很多方法,你可以先停止,然后再启动,或者一直停着不动,静态的嘛
* 导演类嘛,按照什么顺序是导演说了算
*/
}

建造者模式的定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
通用模式:
在这里插入图片描述
角色
Product产品类
通常是实现了模板方法模式,也就是有模板方法和基本方法,这个参考第10章的模板方
法模式。例子中的BenzModel和BMWModel就属于产品类。
Builder抽象建造者
规范产品的组建,一般是由子类实现。例子中的CarBuilder就属于抽象建造者。
ConcreteBuilder具体建造者
实现抽象类定义的所有方法,并且返回一个组建好的对象。例子中的BenzBuilder和
BMWBuilder就属于具体建造者。
Director导演类
负责安排已有模块的顺序,然后告诉Builder开始建造
建造者模式的优点
● 建造者独立,容易扩展
使用建造者模式可以使客户端不必知道产品内部组成的细节,
● 建造者独立,容易扩展

建造者模式的使用场景
● 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式
● 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可
以使用该模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗中的代码猿--刘同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值