大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全家桶1年46,售后保障稳定
老大突然拉住我,喜滋滋地告诉我:“公司很满意我们做的模型,又签订了一个合同,把奔驰、宝马的车辆模型都交给我们公司制作了,不过这次额外增加了一个新需求:汽车的启动、停止、喇叭声音、引擎声音都由客户自己控制,想什么顺序就什么顺序”
那我们开始设计,来看一下类图:
类图比较简单,在CarModel中我们定义了一个setSequence方法,车辆模型的这几个动作 要如何排布,是在这个ArrayList中定义的。然后run()方法根据sequence定义的顺序完成指定 的顺序动作。我们来看模型抽象类代码:
public abstract class CarModel {
//这个参数是各个基本方法执行的顺序
private ArrayList<String> sequence = new ArrayList<>();
//开始跑了
protected abstract void start();
//能停下来
protected abstract void stop();
//喇叭会出声音
protected abstract void alarm();
//引擎会轰隆隆地响
protected abstract void engineBoom();
//模型会跑
final public void run() {
//循环一边,谁在前,就先执行谁
for (String actionName : this.sequence) {
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")) {
//引擎开始轰鸣
this.engineBoom();
}
}
}
//把传递过来的值传递到类内
final public void setSequence(ArrayList<String> sequence) {
this.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 BWMModel 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("宝马车应该这样停车...");
}
}
Client场景类:
class Client{
public static void main(String[] args) {
BenzModel benzModel = new BenzModel();
//存放run的顺序
ArrayList<String> sequence = new ArrayList<>();
sequence.add("engine boom");
sequence.add("start");
sequence.add("stop");
//执行顺序赋予奔驰车
benzModel.setSequence(sequence);
benzModel.run();
}
}
运行结果如下:
我们只满足了一个需求,还有下一个需求呀,然后是第二个宝马模型,只要启动、停止,其他的什么都不要;第三个模型,先喇叭,然后启动,然 后停止;第四个……直到把你逼疯为止,那怎么办?我们就一个一个地来写场景类满足吗? 不可能了,那我们要想办法来解决这个问题,有了!我们为每种模型产品模型定义一个建造者,你要啥顺序直接告诉建造者,由建造者来建造。
抽象汽车组装者:
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 BWMBuilder extends CarBuilder {
private BWMModel bmw = new BWMModel();
public CarModel getCarModel() {
return this.bmw;
}
public void setSequence(ArrayList<String> sequence) {
this.bmw.setSequence(sequence);
}
}
修改后的场景类:
class Client {
public static void main(String[] args) {
ArrayList<String> sequence = new ArrayList<String>();
//客户要求,run时候时候先发动引擎
sequence.add("engine boom");
//启动起来
sequence.add("start");
//开了一段就停下来
sequence.add("stop");
BenzBuilder benzBuilder = new BenzBuilder();
benzBuilder.setSequence(sequence);
CarModel carModel = benzBuilder.getCarModel();
carModel.run();
}
}
我们在做项目时,经常会有一个共识:需求是无底洞,是无理性的,不可能你告诉它不增加需求就不增加,这4个过程(start、stop、alarm、engine boom)按照排列组合有很多种,公司可以随意组合,它要什么顺序的车模我就必须生成什么顺序的 车模,客户可是上帝!那我们不可能预知他们要什么顺序的模型呀,怎么办?封装一下,找 一个导演,指挥各个事件的先后顺序,然后为每种顺序指定一个代码,你说一种我们立刻就 给你生产处理,好方法,厉害!我们先修改一下类图
public class Director {
private ArrayList<String> sequence = new ArrayList();
private BenzBuilder benzBuilder = new BenzBuilder();
private BWMBuilder bmwBuilder = new BWMBuilder();
/*
* 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();
}
public BWMModel getCBMWModel() {
this.sequence.clear();
this.sequence.add("alarm");
this.sequence.add("start");
this.sequence.add("stop");
this.bmwBuilder.setSequence(this.sequence);
return (BWMModel) this.bmwBuilder.getCarModel();
}
/*
* D类型的宝马车只有一个功能,就是跑,启动起来就跑,永远不停止
*/
public BWMModel getDBMWModel() {
this.sequence.clear();
this.sequence.add("start");
this.bmwBuilder.setSequence(this.sequence);
return (BWMModel) this.benzBuilder.getCarModel();
}
}
顺便说一下,大家看一下程序中有很多this调用。如果你要调用类中的成员变量或方法,需要在前面加上this关键字,不加也能正常地跑起来,但是不清晰,加上this关键字,我就是要调用本类中的成员变量或方法,而不是本方法中的一个变量。还有super方法也是一样,是调用父类的成员变量或者方法,那就加上这个关键字,不要省略.
建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:
Separate the construction of a complex object from its representation so that the same construction process can create different representations.(将一个复杂对象的构建与它的表示分 离,使得同样的构建过程可以创建不同的表示。)
建造者模式的优点
使用场景
● 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
● 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。
● 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适。
● 在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程 中不易得到时,也可以采用建造者模式封装该对象的创建过程。该种场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发觉,而要通过创建者模式柔化创建过程,本身已经违反设计的最初目标。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/226770.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...