设计模式—工厂方法模式中提到,该模式中一个工厂只能生产一个产品。。但是在现实生活中,一个工厂往往可以生产多类产品。于是有了抽象工厂模式。

抽象工厂模式(Abstract Factory Pattern),其定义如下:

:::info Provide an interface for creating families of related or dependent objectswithout specifying their concrete classes.

为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类. :::

也就是说,抽象工厂中每个工厂可以创建多种类的产品,而工厂方法每个工厂只能创建一类产品

其组成模型如下:

组成 关系 作用
抽象产品族(Abstract Product) 抽象产品的父类 定义抽象产品的公共接口
抽象产品(Product) 具体产品的父类 提供描述产品的公共接口
具体产品(Concrete Product) 具体产品类,工厂生产的目标类 抽象产品具体化
抽象工厂(Factory) 具体工厂的父类 描述具体工厂的公共接口
具体工厂(Concrete Factory) 抽象工厂的子类;被外界调用 描述具体工厂;实现FactoryMethod工厂方法创建产品的实例

何谓产品族,抽象产品和具体产品。例如:手机就是一个抽象产品组,不同的公司手机对应为抽象产品,例如苹果,小米,华为等,对于抽象产品华为来说,Mate 30,Mate 40等不同机型称之为具体产品。

抽象工厂模式的优点

  1. 降低耦合度。抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展;
  2. 符合开闭原则;新增一种产品类时,只需要增加相应的具体产品类和相应的工厂子类即可;
  3. 符合单一职责原则;每个具体工厂类只负责创建对应的产品;


抽象工厂模式的缺点

  1. 抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了开闭原则。

对于新的产品族符合开闭原则;对于新的产品种类不符合开闭原则。


抽象工厂模式最佳实践

  1. 有多个系列产品,而系统中只消费其中某一系列产品;
  2. 系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现


抽象工厂模式实现步骤

  1. 创建抽象产品族,定义每一产品族的公共接口;
  2. 创建抽象产品,定义产品的公共能力;
  3. 创建具体产品类,实现自己的独有能力;
  4. 创建抽象工厂,定义生产的公共能力;
  5. 创建具体工厂类,实现自己的生成能力,具体到能生产哪种产品;
  6. 外界调用具体工厂生成具体产品。

抽象工厂模式使用示例

某代工厂既代工生产海尔冰箱和空调,也代工生产格力冰箱和空调。

  • 抽象产品族为代工电器,IElectricAppliance类来表示,因为这两者都属于电器,都有一个公共能力,即工作(work);
  • 冰箱抽象为一个类;空调抽象为一个类;
  • 设计两个工厂,一个专门生产海尔的产品,一个专门生产格力的产品
  1. public class AbstractFactory {
  2. /**
  3. * 抽象产品族类,并定义具体产品的基本功能
  4. */
  5. public interface IElectricAppliance {
  6. void work();
  7. }
  8. /**
  9. * 冰箱抽象产品类,并定义具体产品的基本功能
  10. */
  11. public interface IRefrigerator extends IElectricAppliance {
  12. }
  13. /**
  14. * 冰箱抽象产品类,并定义具体产品的基本功能
  15. */
  16. public interface IAirConditioner extends IElectricAppliance {
  17. }
  18. /**
  19. * 具体产品类:海尔冰箱
  20. */
  21. public static class HaierRefrigerator implements IRefrigerator {
  22. @Override
  23. public void work() {
  24. System.out.println("海尔冰箱开始工作");
  25. }
  26. }
  27. /**
  28. * 具体产品类:格力冰箱
  29. */
  30. public static class GreeRefrigerator implements IRefrigerator {
  31. @Override
  32. public void work() {
  33. System.out.println("格力冰箱开始工作");
  34. }
  35. }
  36. /**
  37. * 具体产品类:海尔空调
  38. */
  39. public static class HaierAirConditioner implements IAirConditioner {
  40. @Override
  41. public void work() {
  42. System.out.println("海尔空调开始工作");
  43. }
  44. }
  45. /**
  46. * 具体产品类:格力空调
  47. */
  48. public static class GreeAirConditioner implements IAirConditioner {
  49. @Override
  50. public void work() {
  51. System.out.println("格力空调开始工作");
  52. }
  53. }
  54. /**
  55. * 工厂抽象,提供生产产品的方法
  56. */
  57. public interface IFactory {
  58. IRefrigerator createRefrigerator();
  59. IAirConditioner createAirConditioner();
  60. }
  61. /**
  62. * 海尔类工厂:生产海尔冰箱和海尔空调
  63. */
  64. public static class HaierFactory implements IFactory {
  65. @Override
  66. public IRefrigerator createRefrigerator() {
  67. return new HaierRefrigerator();
  68. }
  69. @Override
  70. public IAirConditioner createAirConditioner() {
  71. return new HaierAirConditioner();
  72. }
  73. }
  74. /**
  75. * 铅笔类工厂
  76. */
  77. public static class GreeFactory implements IFactory {
  78. @Override
  79. public IRefrigerator createRefrigerator() {
  80. return new GreeRefrigerator();
  81. }
  82. @Override
  83. public IAirConditioner createAirConditioner() {
  84. return new GreeAirConditioner();
  85. }
  86. }
  87. public static void main(String[] args) {
  88. // 生产海尔冰箱
  89. new HaierFactory().createRefrigerator().work();
  90. // 生产海尔空调
  91. new HaierFactory().createAirConditioner().work();
  92. // 生产格力冰箱
  93. new GreeFactory().createRefrigerator().work();
  94. // 生产格力空调
  95. new GreeFactory().createAirConditioner().work();
  96. }
  97. }

运行结果如下:

:::success 海尔冰箱开始工作
海尔空调开始工作
格力冰箱开始工作
格力空调开始工作 :::