目录

一、抽象工厂模式

二、UML图示例

三、代码示例

四、优缺点

之前的一篇文章我们介绍了简单工厂模式,今天我们就来介绍一下抽象工厂模式;

一、抽象工厂模式

其实抽象工厂模式相比于简单工厂模式,本质上就是多了一层创建简单工厂的超级工厂,

该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

抽象工厂的组成:

  • 抽象工厂(AbstractFactory)角色:核心,可以是抽象类,可以是接口;
  • 具体工厂(Factory)角色:含有创建产品实例的逻辑;
  • 抽象产品(AbstractProduct)角色:具体工厂所创建的实例的父类或他们拥有的接口;
  • 具体产品(Product)角色:具体的产品实例;

为了更清晰地理解抽象工厂模式,需要先引入两个概念:

产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电

视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。

产品族 :在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视

机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。

java 抽象工厂使用场景_java

 从上边的图中我们可以更清晰的看到同族产品和同一等级结构的产品的联系和区别。

我们还可以通过下边的相图可以更加清楚的看出来,横轴表示等级结构,向横轴做垂线,在同一条垂线上的是同一个等级结构,纵轴便是产品组,向纵轴做垂线,同一条垂线上的是一个产品族。

java 抽象工厂使用场景_java_02

二、UML图示例

下面我们以形状和颜色工厂来代码模拟抽象工厂代码结构关系:

java 抽象工厂使用场景_抽象工厂模式_03

如果所示:AbstractFactory就是抽象工厂,它负责生成ShapeFactory形状工厂和ColorFactory颜色工厂;ShapeFactory工厂可以根据Shape接口生成不同的形状实例;ColorFactory可以根据Color生成不同的颜色实例;

三、代码示例

步骤1:创建2个接口,形状接口和颜色接口;

public interface Shape {
   void draw();
}

具体实现的类省略...
public interface Color {
   void fill();
}

具体实现的类省略...

步骤2:为Color和Shape对象创建抽象类来获取工厂

public abstract class AbstractFactory {
   public abstract Color getColor(String color);
   public abstract Shape getShape(String shape) ;
}

步骤3:创建扩展了 AbstractFactory 的简单工厂类ShapeFactory和ColorFactory,基于给定的信息生成实体类的对象;

public class ShapeFactory extends AbstractFactory {
   @Override
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      return null;
   }
}

步骤4:创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂;

public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
      if(choice.equalsIgnoreCase("SHAPE")){
         return new ShapeFactory();
      } else if(choice.equalsIgnoreCase("COLOR")){
         return new ColorFactory();
      }
      return null;
   }
}

步骤5:使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象

public class AbstractFactoryPatternDemo {
   public static void main(String[] args) { 
      //获取形状工厂
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
      //获取形状为 Circle 的对象
      Shape shape1 = shapeFactory.getShape("CIRCLE"); 
      //调用 Circle 的 draw 方法
      shape1.draw();     
      //获取形状为 Square 的对象
      Shape shape2 = shapeFactory.getShape("SQUARE"); 
      //调用 Square 的 draw 方法
      shape2.draw();
 
      //获取颜色工厂  后续方法参考获取形状的,省略
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
    }
}

四、优缺点

优点:

  1. 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建;
  2. 抽象工厂模式可以实现高内聚低耦合的设计目的;
  3. 符合“开闭原则”,增加具体产品或具体工厂都很方便,无须修改系统其它工厂逻辑;

缺点:

  1. 添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
  2. 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦,具体可看条目一的海尔和长虹产品等级结构图)