1.产生背景
- 为什么需要建造者模式
建造者模式仍然是对上一节设计模式(抽象工厂模式)的改进;
抽象工厂模式侧重一个工厂可以创建一组相关的对象;但是这组相关对象是平等地位,没有主次之分,也没有整体与部分的概念,如何使用由客户决定;
但是,现实中有一些对象的创建非常复杂,依赖很多其它对象,在创建自身时,需要先创建一批依赖的对象,然后再把这些依赖的对象,组装成最终的对象;
比如:生产一辆汽车,需要先创建底盘、轮胎、发动机等各个零件,最重需要把这些零件组装到一起,才能制造出最终的产品:汽车;
这些零部件在业务是相关的,而且汽车本身有很多品牌、车型,很符合抽象工厂,但是,如果使用抽象工厂模式,则创建的是一堆零件,必须由客户自己组装才能创建出最终的产品;
这使得,客户需要一个复杂对象时,这个复杂对象的创建过程非常复杂,而大部分情况,客户并不关心对象的创建过程,只需要对象提供的服务;
2.概念
建造者模式是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
本质:侧重抽像与实现的分类,但实际上针对的是复杂对象的零件创建与零件组装;
3.目的
解决 复杂对象创建与组装的复杂性
4.解决方案
本质:把对象依赖的零件创建、零件的组装封装起来;以使客户很方便的获取一个复杂对象;
与抽象工厂区别:增加一个装配(组装)功能;
- 增加一个组装类,专门负责零件的组装;
- 或者:增加一个组装方法,负责零件的组装
根据以上分析,抽象工厂创建的产品是一堆相关性的零部件,无法产生最终的产品,如果需要最终的产品(汽车),则需要客户自己组装;
//汽车零件制造厂
public interface ICarPartsFactory{
IUnderpan createUnderPan();//创建底盘
IEngine createEngine();//创建发动机
ITyre createTyre();//创建轮胎
}
//福特零件汽车制厂
public class FordCarPartsFactory{
//创建底盘
IUnderpan createUnderPan(){
return 福特底盘;
}
//创建发动机
IEngine createEngine(){
return 福特发动机;
}
//创建轮胎
ITyre createTyre(){
return 福特轮胎;
}
}
//组装
public class Directory{
ICar constraut(int type){
if(type == 1){
//创建零件工厂
ICarPartsFactory f = new FordCarPartsFactory()
IUnderpan underpan = f.createUnderPan();
IEngine engine = f.createEngine();
ITyre tyre = createTyre();
//组装
ICar car = new FatCar();
car.setUnderpan(underpan);
car.setEngine(engine);
car.setTyre(tyre);
return car;
}else if(type == 2){
return 其它品牌汽车
}
return null;
}
}
//客户
public class Client{
Directory dir = new Directory();
ICar car = dir.constraut(1);
car.start();//滴滴,开车了;
}
从以上伪代码,可以通用Directory组装类来简化最终产品的组装,客户只需要与组装类交互就可以;
上面的代码,其实就是建造者模式: (非静态)简单工厂 + 工厂方法模式;
Directory :这个组装功能类,就是建造模式中的导演类;它本身是一个非静态的简单工厂类
变种
以上代码Directory是一个独立的类,但是只有一个组装方法,通常,为了简单,会把这个组装方法迁移到工厂内;
与抽象工厂区别:: 增加一个配置类,或者增加一个组装方法;
5. 类图
6.优缺点
优点:
- 简单化了复杂对象的创建
通过组装方法,隐藏内部的创建过程; - 可扩展
继承自工厂方法的可扩展性;
最核心的目的:保证可扩展的前提下,减小复杂对象创建过程的复杂性
缺点:
- 复杂对象的零部件必须具有共同点
这是使用建造者模式可扩展的基本条件;