1、介绍
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
意思是:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。
2、使用场景
当一个对象族(或一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。例如,应用需涉及不同的操作系统时,若是需要在三个不同的平台(Windows、Linux、Android)上运行,可以通过抽象工厂模式屏蔽掉操作系统对应用的影响。
3、UML类图
角色介绍:
- AbstactFactory:是工厂模式的核心,与应用系统无关,具有的工厂类必须实现这个接口。
- ConcreteFactory:实现了抽象工厂接口,含所有选择合适产品对象的逻辑,并且受到应有程序的调用以创建产品对象
- Product:负责定义产品的共性
- ConcreteProduct:实现抽象产品角色所声明的接口
4、示例
在上一章阐述了车厂生产车,但是车厂发现一个问题,虽然Q1和Q2都是一个车系,但两者的区别很大,例如:Q1轮胎是普通的,发动机是国产的;Q2轮胎是越野轮胎,发动机是进口的。这就可以将抽象工厂应用到其中。
抽象车厂类
public abstract class CarFactory {
/**
* 生产轮胎
* @return 轮胎
*/
public abstract ITire createTire();
/**
* 生产发动机
* @return 发动机
*/
public abstract IEngine createEngine();
}
具体Q1、Q2工厂类
public class Q1Factory extends CarFactory{
@Override
public ITire createTire() {
return new NormalTire();
}
@Override
public IEngine createEngine() {
return new DomesticEngine();
}
}
public class Q2Factory extends CarFactory{
@Override
public ITire createTire() {
return new SUVTire();
}
@Override
public IEngine createEngine() {
return new ImportEngine();
}
}
为每一种零件产品定义一个接口,轮胎具体有普通和越野之分,发动机具体有国产和进口之分。
轮胎相关类如下:
public interface ITire {
/**
* 轮胎
*/
public abstract 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 {
/**
* 引擎
*/
public abstract void engine();
}
public class DomesticEngine implements IEngine{
@Override
public void engine() {
System.out.println("生产国产引擎");
}
}
public class ImportEngine implements IEngine{
@Override
public void engine() {
System.out.println("生产进口引擎");
}
}
最后,我们在一个Client客户类中模拟
public class Client {
public static void main(String[] args) {
System.out.println("Q1生产车间:");
CarFactory factoryQ1 = new Q1Factory();
factoryQ1.createTire().tire();
factoryQ1.createEngine().engine();
System.out.println("Q2生产车间:");
CarFactory factoryQ2= new Q2Factory();
factoryQ2.createTire().tire();
factoryQ2.createEngine().engine();
}
}
输出结果如下:
Q1生产车间:
生产普通轮胎
生产国产引擎
Q2生产车间:
生产越野轮胎
生产进口引擎
5、总结
优点:
- 分离接口与实现,客户端使用抽象工厂来创建具体的对象,无需关心具体实现,只是面向产品的接口编程而已,使其从具体的产品实现中解耦,同时基于接口与实现的分离,使得切换产品类时灵活容易
缺点:
- 类文件的爆炸性增加。
- 不太容易扩展新的产品类,因为增加一个产品类就需要修改抽象工厂,所有的具体工厂类均会修改。