定义
提供一个创建一系列相关或者相互依赖对象的接口,而无需指定他们具体的类
本质
选择产品簇的实现
登场角色
-
AbstractProduct(抽象产品)
抽象产品角色,为每种产品声明接口
-
AbstractFactory(抽象工厂)
声明了一组用于创建一种产品的方法,每一个方法对应一种产品。
-
ConcreteProduct(具体产品)
具体的产品实现定义,负责实现抽象产品角色定义的接口,是具体工厂生产的具体的产品对象。
-
ConcreteFactory(具体工厂)
具体的工厂,实现了在抽象工厂中定义的创建产品的方法,生成一组具体的产品,这些产品构成了一个产品种类,每一个产品都位于某个产品等级结构中。
示例代码
/**
* 轮胎接口
*/
public interface ITire {
void tire();
}
/**
* 普通轮胎
*/
public class NormalTire implements ITire{
@Override
public void tire() {
System.out.println("普通轮胎");
}
}
/**
* 越野轮胎
*/
public class SUVTire implements ITire {
@Override
public void tire() {
System.out.println("越野轮胎");
}
}
/**
* 发动机
*/
public interface IEngine {
void engine();
}
/**
* 国产发动机
*/
public class DemosticEngine implements IEngine{
@Override
public void engine() {
System.out.println("国产发动机");
}
}
/**
* 进口发动机
*/
public class ImportEngine implements IEngine{
@Override
public void engine() {
System.out.println("进口发动机");
}
}
/**
* 制动系统
*/
public interface IBrake {
void brake();
}
/**
* 普通制动
*/
public class NormalBrake implements IBrake{
@Override
public void brake() {
System.out.println("普通制动");
}
}
/**
* 高级制动
*/
public class SeniorBrake implements IBrake{
@Override
public void brake() {
System.out.println("高级制动");
}
}
/**
* 抽象工厂类
*/
public abstract class CarFactory {
/**
* 生产轮胎
*/
public abstract ITire createTire();
/**
* 生产发动机
*/
public abstract IEngine createEngine();
/**
* 生产制动系统
*/
public abstract IBrake createBrake();
}
/**
* 创建Q3的工厂
*/
public class Q3Factory extends CarFactory{
@Override
public ITire createTire() {
return new NormalTire();
}
@Override
public IEngine createEngine() {
return new DemosticEngine();
}
@Override
public IBrake createBrake() {
return new NormalBrake();
}
}
/**
* 创建Q7的工厂
*/
public class Q7Factory extends CarFactory{
@Override
public ITire createTire() {
return new SUVTire();
}
@Override
public IEngine createEngine() {
return new ImportEngine();
}
@Override
public IBrake createBrake() {
return new SeniorBrake();
}
}
public class Client {
public static void main(String args[]){
//生产Q3的工厂
CarFactory factoryQ3 = new Q3Factory();
factoryQ3.createTire().tire();
factoryQ3.createEngine().engine();
factoryQ3.createBrake().brake();
System.out.println("===============");
//生产Q7的工厂
CarFactory carFactoryQ7 = new Q7Factory();
carFactoryQ7.createTire().tire();
carFactoryQ7.createEngine().engine();
carFactoryQ7.createBrake().brake();
}
}
运行结果
普通轮胎
国产发动机
普通制动
===============
越野轮胎
进口发动机
高级制动
功能
抽象工厂模式是为一系列相关对象或者相互依赖的对象创建一个接口。抽象工厂其实是一个产品系列,后者是产品簇,比如上述代码中的抽象工厂可以看成是一个汽车簇,有几种不同的汽车生产方案,上述代码中实现了Q3Factory和Q7Factory两种方案,对应两种具体的工厂类,而这两种工厂类对象也是相关联的对象。而对于轮胎、发动机和制动系统来说,每一种也是一组相关的对象,比如普通轮胎和越野轮胎是相关对象,国产发动机和进口发动机是相关对象,普通制动和高级制动是相关对象。轮胎、发动机和制动系统的这些关联对象构成了一个产品簇,各从中抽取一种恰好组成一个产品,而抽象工厂就是定义了这样一个产品簇。
优点
- 分离接口和实现。客户端使用抽象工厂创建需要的对象,而客户端根本不知道具体的实现是谁,客户端只是面向产品的接口编程而已,也就是说,客户端从具体的产品实现中解耦,交由工厂去实现,该点和简单工厂模式时相同的。
- 使得切换产品变得容易,比如上面代码中的Q3和Q7两种方案,只需要将Q3Factory切换为Q7Factory就可以由Q3方案切换为Q7方案,即选择不同的工厂实现类,就可以得到不同的产品方案。
缺点
- 不同容易扩展新的产品。比如,如果想要给产品簇添加一个新的产品,比如水箱,就需要修改抽象工厂,那么所有的工厂的实现类都需要修改。
- 类层次结构更加复杂。因为类文件爆炸性增加。
和简单工厂模式的区别
简单工厂名模式时选择单个产品的实现,虽然一个类里面可以有多个工厂方法,但是这些方法之间一般是没有联系的,即使看起来好像有联系。
但是抽象工厂方法着重的是一个产品簇选择实现,定义在抽象工厂方法里面的方法通常是有联系的,他们都是产品的某一部分或者是相互依赖的,如果抽象工厂方法里面只定义了一个方法,直接创建产品,那么就退化为工厂方法了。
何时选用
- 如果希望一个系统独立于他的产品的创建、组合和表示的时候,换句话说,希望一个系统只是知道产品的接口,而不关心其其实现的时候。
- 如果一个系统需要由多个产品系列中的一个来配置的时候,换句话说就是可以动态的切换不同的产品。
- 如果要强调一系列相关产品的接口,以便联合使用他们的时候。