工厂模式分为抽象工厂模式和工厂方法模式(简单工厂模式属于工厂方法模式的一种)
工厂模式跟它的名称很贴近,很容易顾名思义,工厂嘛生产产品的,工厂模式就是创建对象的一种方式,为创建对象提供过度接口,隐藏了对象创建的具体细节。
工厂方法模式与抽象工厂模式都需要具备4个角色:抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色。
工厂方法模式我们举个简单的例子,总统需要宝马车和奔驰车满足日常需要。总统每次坐车呢不需要每次都喊开奔驰车,开宝马车,只需要喊开车就行了。具体的开什么车由司机根据需要确定。
抽象工厂模式是创建工厂的工厂。首先我们要了解一下产品族的概念,位于不同产品等级结构中,功能相关联的产品组成的家族,比如宝马和奔驰都有运动系列和商务系列,那么运动系列和商务系列就是两个产品族。那么抽象工厂模式的设计初衷是提供多个接口,每个接口可以创建一个产品族中的多个对象。
工厂方法模式 代码举例
目录结构
产品
Car.java
BenzCar.java
BmwCar.java
工厂
Driver.java
BenzDriver.java
BmwDriver.java
主类
main.java
抽象工厂模式 代码举例
目录结构
产品
BusinessCar.java
SportCar.java
BmwSportCar.java
BmwBusinessCar.java
BenzSportCar.java
BenzBusinessCar.java
工厂
AbstractFactory.java
BusinessCarFactory.java
SportCarFactory.java
FactoryProductor.java
我们可以看到其实工厂模式的约束是很松的,产品的构建细节由产品自身决定。
可以不可以去掉接口?从代码可运行上来讲,去掉一点问题没有,但是我们要回过头来考虑一下为什么会有工厂模式?
我们完全可以忽略甚至放弃面向对象相对于面向函数的优势-抽象,这种优势只有当我们使用的时候才会发现其便利的地方。
这个工厂完全可以再建立几条除汽车之外的生产线,比如食品加工,空调装配等等。这些毫不相关的生产线放到一个工厂里面的结果就是混乱。
当我们使用的时候要查看手册,看这个工厂都可以生产什么东西,每个东西都怎么使用,本来是为了代码简洁,使用方便现在倒成了负担。
当然工厂模式的缺陷也很明显,它并没有完全避免代码改动,当有新产品加入时,我们也需要添加对应的工厂类,而且当产品角色的创建条件发生变化时,
我们也需要修改对应的工厂角色。
所以一般我们在一下条件满足时考虑使用工厂模式:
1,用户不需要知道创建的具体细节
2,类对象存在变动的可能,或者根本不知道使用哪一个具体的对象
工厂模式实例应用:
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时
工厂模式跟建造者模式的主要区别在于工厂模式产品内部的具体创建过程由产品自身来完成(举例)而建造者模式产品的生产是“外部化”的,由指导者指导建设者统一执行。建造者模式着重于逐步将组件装配成一个产品并向外提供产品,而抽象工厂模式着重于得到产品族中的多个产品对象。
工厂模式中的抽象接口不是强制的,如果不考虑场景,即使去掉抽象接口抽象工厂模式不受影响,但是建造者模式中的抽象接口就不能随便去掉,因为指导者指导建造者创建具体产品这个行为是统一的。