前言
关于两者的使用方法本文不再阐述
关于两者的区别本文不再详细阐述
讲的优秀的文章随便一搜就可以找的到,但是相同的文章多了就会破坏搜索质量。
选题原因
在学完工厂方法模式与建造者模式以后,忽然萌生出二者是否可以结合以及如何结合的想法。
通过实践证实两者可以结合(但并不确定在实际的生产过程中能真正用的上),在实践完成后,再通过网上搜索了相关内容,发现该内容并不多见,找到了一篇关于 该思考的文章。
但是通过比较,发现该文中关于此内容不太合理的地方(仅仅是个人看法,后面的内容会详细说)。本文通过建造车来展开讨论
实现过程
-
1.类图
- 类图看起来比较复杂(额,真的尽力了)。
- 先梳理一下:
- AbstractCarModel: 抽象类,是产品[汽车模型]的抽象类,下面的实现类有BenzSCarModel,BMW3CarModel,BMW7CarModel。
-
AbstractCarBuilder:抽象类,是建造者[汽车生产线]的抽象类,BMWCarBuilder与BenzCarBuilder也是抽象类,继承了AbstractCarBuilder,在这里并没有具体的看出它的作用是什么,但是我们可以在日后进行扩展,比如不同公司的生产线可能存在一些不同,而将此不同写入这个抽象类,而且这样写也会让类之间更加的有层次。
BMW3CarBuilder、BMW7CarBuilder、BenzSCarBuilder分别为建造者具体实现类[具体生产线]。 - Factory:工厂接口,BMWCarFactroy、BenzCarFactory为其具体的实现。
-
Director:指挥者,负责生产方案的预设(生产顺序,生产内容),以及得到具体的Car。
OK,关系梳理完了,下面来具体讲解 -
AbstractCarModel:上面已经说了它是一个汽车模型,暂时拥有属性[发动机,轮胎,方向盘],还有一个可以判断是否可以跑起来的run()(默认情况下三者都不为空即可判断可以跑起来)。其下的具体实现类BMW3CarModel对run()进行了重写(可以不用发动机也能跑起来)。BMW7CarModel添加了GPS功能。根据能否跑起来来判断是否建车成功。
注意:如果直接new某一个汽车模型,是不能跑起来的,因为需要安装各个部件才能跑起来。
- AbstractCarBuilder:建造者[生产线],拥有抽象方法[安装发动机,安装轮胎,安装方向盘],并维护了一个List数组programme,用于存储生产方案,setProgramme()为上层调用,给生产线一个生产方案。start()是按照生产方案的顺序一步一步组装(也就是设置模型的属性不为空)。getModel()是返回model对象。
-
Factory:工厂,接口内部的方法利用java反射,传入具体的类对象返回该类的对象实例。
注意:这里的工厂生产的是builder,把builder作为工厂的产品。
-
Director:首先实例化了两种工厂(宝马和奔驰工厂),然后是一个数组来保存生产方案。其他的方法是生产不同的产品。
Director本应属于建造者模式中的一部分,如今却被用到了工厂之上,它原本的作用就是设置生产顺序(即使没有List数组方案),用在工厂之上它的作用也没有发生变化。
Director调用顺序
①拿到工厂实例,创建建造者[具体生产线](需要传入具体生产线的Class对象)
②为List数组programme赋值(制定生产方案),并调用建造者的setProgramme()告诉建造者生产方案。
③调用建造者的start()方法对汽车进行建造。
④调用建造者的getModel()方法获取汽车实例。
⑤返回汽车实例,完成汽车建造。
3.比较
-
为什么我说
该文章有不合理的地方?
工厂生产产品,只专注于最终得到产品,建造者生产产品关注产品细节,确实没有问题,但是在两种模式的结合之下,工厂生产的产品如果与建造者生产相同的类对象下就会有问题。建造者生产产品的类对象是一个壳子,然后对其一步一步填充,最后得到一个可用的产品(先是一个车模型,然后对车一步一步组装,最后得到车实例)。而如果工厂直接获取产品也只能得到产品的壳子(没有builder的组装,只能得到一个车模型[不能跑起来])。
不能代表谁对谁错,只是不同的思考方式,但我觉得该文作者应该忽略了上面所提到的问题。
4.代码实现
-
AbstractCarModel
package Model;
public abstract class AbstractCarModel {
protected String wheel;//轮子
protected String steeringWheel;//方向盘
protected String engine;//发动机
//判断能否跑起来
public void run(String name) {
if(wheel==null||steeringWheel==null||engine==null) {
System.out.println(name+"跑不起来");
}else {
System.out.println(name+"跑起来了");
}
}
public String getWheel() {
return wheel;
}
public void setWheel(String wheel) {
this.wheel = wheel;
}
public String getSteeringWheel() {
return steeringWheel;
}
public void setSteeringWheel(String steeringWheel) {
this.steeringWheel = steeringWheel;
}
public String getEngine() {
return engine;
}
public void setEngine(String engine) {
this.engine = engine;
};
}
: BenzSCarModel
package Model;
public class BenzSCarModel extends AbstractCarModel{
}
: BMW3CarModel
package Model;
public class BMW3CarModel extends AbstractCarModel{
@Override
public void run(String name) {
if(super.wheel==null||super.steeringWheel==null) {
System.out.println(name+"跑不起来");
}else {
System.out.println(name+"跑起来了");
}
}
}
: BMW3CarModel
package Model;
public class BMW7CarModel extends AbstractCarModel{
private String GPS;
public String getGPS() {
return GPS;
}
public void setGPS(String gPS) {
GPS = gPS;
}
}
: AbstractCarBuilder
package Builder;
import java.util.ArrayList;
import java.util.List;
import Model.AbstractCarModel;
public abstract class AbstractCarBuilder {
public abstract void installWheel();
public abstract void installSteeringwheel();
public abstract void installEngine(String model);
/**
* 获取模型
*/
public abstract AbstractCarModel getModel();
/**
* 制定生产方案
*/
protected List<String> programme=new ArrayList<String>();
public void setProgramme(List<String> programme) {
this.programme=programme;
}
/**
* 开始组装
*/
public void start() {
for (String part : programme) {
if(part.equals("wheels")) {
this.installWheel();
}else if(part.equals("Steeringwheel")) {
this.installSteeringwheel();
}else if(part.matches("engine[A-Z]?")) {
this.installEngine(part);
}else{
System.out.println("没有该组件,请检查方案");
}
}
if(programme.size()==0) {
System.out.println("请先设置方案");
}else {
System.out.println("车辆组装成功");
}
}
}
: BenzCarBuilder
package Builder;
public abstract class BenzCarBuilder extends AbstractCarBuilder{
}
: BMWCarBuilder
package Builder;
public abstract class BMWCarBuilder extends AbstractCarBuilder{
}
: BenzSCarBuilder
package Builder;
import Model.AbstractCarModel;
import Model.BenzSCarModel;
public class BenzSCarBuilder extends BenzCarBuilder{
//先造一个空壳车
private BenzSCarModel benzCarModel=new BenzSCarModel();
//下面的方法都是填充空壳车
@Override
public void installWheel() {
benzCarModel.setWheel("我有轮子了");
System.out.println("奔驰S级车安装了轮子");
}
@Override
public void installSteeringwheel() {
benzCarModel.setSteeringWheel("我有轮子了");
System.out.println("奔驰车S级车安装了方向盘");
}
@Override
public void installEngine(String model) {
benzCarModel.setEngine("我有发动机"+model);
System.out.println("奔驰车S级车安装了"+model);
}
//返回该车模型
@Override
public AbstractCarModel getModel() {
return benzCarModel;
}
}
: BMW3CarBuilder
package Builder;
import Model.BMW3CarModel;
import Model.AbstractCarModel;
public class BMW3CarBuilder extends BMWCarBuilder{
private BMW3CarModel bmw3CarModel=new BMW3CarModel();
@Override
public AbstractCarModel getModel() {
return bmw3CarModel;
}
@Override
public void installWheel() {
bmw3CarModel.setWheel("我有轮子了");
System.out.println("宝马3系车安装了轮子");
}
@Override
public void installSteeringwheel() {
bmw3CarModel.setSteeringWheel("我有方向盘了");
System.out.println("宝马3系车安装了方向盘");
}
@Override
public void installEngine(String model) {
bmw3CarModel.setEngine("我有发动机"+model);
System.out.println("宝马3系车安装了"+model);
}
}
: BMW7CarBuilder
package Builder;
import Model.AbstractCarModel;
import Model.BMW7CarModel;
public class BMW7CarBuilder extends BMWCarBuilder{
private BMW7CarModel bmw7CarModel=new BMW7CarModel();
@Override
public AbstractCarModel getModel() {
return bmw7CarModel;
}
@Override
public void installWheel() {
bmw7CarModel.setWheel("我有轮子了");
System.out.println("宝马7系车安装了轮子");
}
@Override
public void installSteeringwheel() {
bmw7CarModel.setSteeringWheel("我有方向盘了");
System.out.println("宝马7系车安装了方向盘");
}
@Override
public void installEngine(String model) {
bmw7CarModel.setEngine("我有发动机"+model);
System.out.println("宝马7系车安装了"+model);
}
public void installGPS() {
bmw7CarModel.setGPS("我有GPS了");
System.out.println("宝马7系车安装了GPS");
}
@Override
public void start() {
for (String part : super.programme) {
if(part.equals("wheels")) {
this.installWheel();
}else if(part.equals("Steeringwheel")) {
this.installSteeringwheel();
}else if(part.matches("engine[A-Z]?")) {
this.installEngine(part);
}else if(part.matches("GPS")){
this.installGPS();
}else {
System.out.println("没有该组件,请检查方案");
}
}
if(programme.size()==0) {
System.out.println("请先设置方案");
}else {
System.out.println("车辆组装成功");
}
}
}
: Factory
package Factory;
import Builder.AbstractCarBuilder;
public interface Factory {
//根据传入的Class对象返回对应的实例
public AbstractCarBuilder createBuilder(Class<?> c);
}
: BenzCarFactory
package Factory;
import Builder.AbstractCarBuilder;
import Builder.BenzCarBuilder;
public class BenzCarFactory implements Factory{
@Override
public AbstractCarBuilder createBuilder(Class<?> c) {
AbstractCarBuilder benzCarBuilder=null;
try {
benzCarBuilder= (BenzCarBuilder) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return benzCarBuilder;
}
}
: BMWCarFactroy
package Factory;
import Builder.BMWCarBuilder;
import Builder.AbstractCarBuilder;
public class BMWCarFactroy implements Factory{
@Override
AbstractCarBuilder bmwCarBuild=null;
try {
bmwCarBuild=(BMWCarBuilder) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bmwCarBuild;
}
}
: Director
package main;
import java.util.ArrayList;
import java.util.List;
import Builder.BMW3CarBuilder;
import Builder.BMW7CarBuilder;
import Builder.BenzSCarBuilder;
import Builder.AbstractCarBuilder;
import Factory.BMWCarFactroy;
import Factory.BenzCarFactory;
import Factory.Factory;
import Model.BMW3CarModel;
import Model.BMW7CarModel;
import Model.BenzSCarModel;
public class Director {
//生产方案
private List<String> programme=new ArrayList<String>();
//宝马工厂
private Factory bmwFactory=new BMWCarFactroy();
//奔驰工厂
private Factory benzFactory=new BenzCarFactory();
public Director() {
this.getHighBMW3CarModel();
this.getLowBMW3CarModel();
BMW7CarModel bmw7CarModel=this.getBMW7CarModel();
System.out.println("--------------");
BenzSCarModel benzSCarModel=this.getBenzSCarModel();
System.out.println("--------------");
bmw7CarModel.run("bmw7Car");
System.out.println("--------------");
benzSCarModel.run("benzSCar");
}
//生产高端宝马3
public BMW3CarModel getHighBMW3CarModel() {
//采用最好发动机的宝马3系高端车
//设置生产方案
programme.clear();
programme.add("wheels");
programme.add("Steeringwheel");
programme.add("engineA");
//获取对应的builder对象
AbstractCarBuilder bmw3carBuilder=bmwFactory.createBuilder(BMW3CarBuilder.class);
//将方案设置给建造者
bmw3carBuilder.setProgramme(programme);
BMW3CarModel bmw3CarModel=(BMW3CarModel) bmw3carBuilder.getModel();
//组装前尝试运行
bmw3CarModel.run("HighBMW3Car");
bmw3carBuilder.start();//组装
bmw3CarModel.run("HighBMW3Car");//组装后再次运行
System.out.println("--------------");
return bmw3CarModel;
}
//生产低端宝马3
public BMW3CarModel getLowBMW3CarModel() {
//没有发动机的宝马3系低端车
programme.clear();
programme.add("wheels");
programme.add("Steeringwheel");
AbstractCarBuilder bmw3carBuilder=bmwFactory.createBuilder(BMW3CarBuilder.class);
bmw3carBuilder.setProgramme(programme);
bmw3carBuilder.start();
BMW3CarModel bmw3LowCarModel=(BMW3CarModel) bmw3carBuilder.getModel();
bmw3LowCarModel.run("bmw3LowCar");
System.out.println("--------------");
return (BMW3CarModel)bmw3LowCarModel;
}
//生产BMW7
public BMW7CarModel getBMW7CarModel() {
programme.clear();
programme.add("wheels");
programme.add("Steeringwheel");
programme.add("engineB");
programme.add("GPS");
AbstractCarBuilder bmw7carBuilder=bmwFactory.createBuilder(BMW7CarBuilder.class);
bmw7carBuilder.setProgramme(programme);
bmw7carBuilder.start();
return (BMW7CarModel)bmw7carBuilder.getModel();
}
//生产奔驰S
public BenzSCarModel getBenzSCarModel() {
programme.clear();
programme.add("engineC");
programme.add("wheels");
programme.add("Steeringwheel");
AbstractCarBuilder benzScarBuilder=benzFactory.createBuilder(BenzSCarBuilder.class);
benzScarBuilder.setProgramme(programme);
benzScarBuilder.start();
return (BenzSCarModel)benzScarBuilder.getModel();
}
}
The more I share, the more I have.
如有建议或错误,欢迎指正。联系方式h1096938190@163.com.
I love technology.And you?