【从零开始学设计模式】第四章_抽象工厂模式(与工厂模式区分)

第四章_抽象工厂模式(与工厂模式区分)

1.介绍

1.1定义

为访问类提供一个创建一组相关或相互依赖对象的接口,且==访问类无须指定所要产品的具体类==就能得到同族的不同等级的产品的模式结构;

1.2解决的问题

主要解决接口选择的问题。

1.3应用实例

  • 系统中有多个产品族, 每个具体工厂创建同族但属于不同等级的产品;
  • 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

1.5角色

  • 抽象产品(Abstract Product):定义了一组产品对象的共同接口或抽象类,描述了产品对象的公共方法。

  • 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性。

  • 抽象工厂(Abstract Factory):声明了一组用于创建产品对象的方法,每个方法对应一种产品类型。抽象工厂可以是接口或抽象类。

  • 具体工厂(Concrete Factory):实现了抽象工厂接口,负责创建具体产品对象的实例。

2.举例

创建 Shape 接口和实现这些接口的实体类。下一步是创建抽象工厂类 AbstractFactory。接着定义工厂类 ShapeFactoryColorFactory,这两个工厂类都是实现了 AbstractFactory。然后创建一个工厂创造器/生成器类 FactoryProducer

AbstractFactoryPatternDemo 类使用 FactoryProducer 来获取 AbstractFactory 对象。它将向 AbstractFactory 传递形状信息 ShapeCIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。同时它还向 AbstractFactory 传递颜色信息 ColorRED / GREEN / BLUE),以便获取它所需对象的类型。

image-20240205192704328

  • 步骤1:为形状和颜色创建一个接口
public interface Shape {
   
   void draw();
}
public interface Color {
   
   void fill();
}
  • 步骤2:分别创建实现形状和颜色的实体类
//实现形状接口的实体类
public class Rectangle implements Shape {
   
 
   @Override
   public void draw() {
   
      System.out.println("Inside Rectangle::draw() method.");
   }
}

public class Square implements Shape {
   
 
   @Override
   public void draw() {
   
      System.out.println("Inside Square::draw() method.");
   }
}

public class Circle implements Shape {
   
 
   @Override
   public void draw() {
   
      System.out.println("Inside Circle::draw() method.");
   }
}
//实现颜色接口的实体类
public class Red implements Color {
   
 
   @Override
   public void fill() {
   
      System.out.println("Inside Red::fill() method.");
   }
}

public class Green implements Color {
   
 
   @Override
   public void fill() {
   
      System.out.println("Inside Green::fill() method.");
   }
}

public class Blue implements Color {
   
 
   @Override
   public void fill() {
   
      System.out.println("Inside Blue::fill() method.");
   }
}
  • 步骤3:为Color和Shape接口对象创建抽象类来获取工厂
public abstract class AbstractFactory {
   
   public abstract Color getColor(String color);
   public abstract Shape getShape(String shape);
}
  • 步骤4:创建继承AbstractFactory的工厂类,基于给定的信息生成实体类的对象
//ShapeFactory:Shape工厂
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("RECTANGLE")){
   
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
   
         return new Square();
      }
      return null;
   }
   
   @Override
   public Color getColor(String color) {
   
      return null;
   }
}
//ShapeFactory:Shape工厂
public class ColorFactory extends AbstractFactory {
   
    
   @Override
   public Shape getShape(String shapeType){
   
      return null;
   }
   
   @Override
   public Color getColor(String color) {
   
      if(color == null){
   
         return null;
      }        
      if(color.equalsIgnoreCase("RED")){
   
         return new Red();
      } else if(color.equalsIgnoreCase("GREEN")){
   
         return new Green();
      } else if(color.equalsIgnoreCase("BLUE")){
   
         return new Blue();
      }
      return null;
   }
}
  • 步骤5:创建一个工厂创造器,通过传递形状或颜色信息来获取指定的工厂
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;
   }
}
  • 消费者:通过FactoryProducer来获取AbstracFactory,进而通过传递类型信息来获取实体类对象
public class AbstractFactoryPatternDemo {
   
   public static void main(String[] args) {
   
 
      //获取形状工厂
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
 
      //获取形状为 Circle 的对象
      Shape shape1 = shapeFactory.getShape("CIRCLE");
 
      //调用 Circle 的 draw 方法
      shape1.draw();
 
      //获取形状为 Rectangle 的对象
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
      //调用 Rectangle 的 draw 方法
      shape2.draw();
      
      //获取形状为 Square 的对象
      Shape shape3 = shapeFactory.getShape("SQUARE");
 
      //调用 Square 的 draw 方法
      shape3.draw();
 
      //获取颜色工厂
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
 
      //获取颜色为 Red 的对象
      Color color1 = colorFactory.getColor("RED");
 
      //调用 Red 的 fill 方法
      color1.fill();
 
      //获取颜色为 Green 的对象
      Color color2 = colorFactory.getColor("GREEN");
 
      //调用 Green 的 fill 方法
      color2.fill();
 
      //获取颜色为 Blue 的对象
      Color color3 = colorFactory.getColor("BLUE");
 
      //调用 Blue 的 fill 方法
      color3.fill();
   }
}
  • 执行结果

    image-20240205192704328

3.优缺点

3.1优点

  • 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类进行管理;
  • 当增加一个新的产品族时不需要修改原代码,满足开闭原则。

3.2缺点

  • 当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

4.小结

  • 工厂模式和抽象工厂的异同
    • 工厂模式和抽象工厂都是创建对象的设计模式
    • 创建对象的方式和对象的组织结构不同
      • 工厂模式式通过一个工厂类来创建一个具体的对象
      • 抽象工厂是通过一组相关的工厂来创建一组相关的对象
      • 工厂模式只适用于单一产品的创建
      • 抽象工厂适用于一组相关产品的创建

祥讲创建对象的过程:

  • 工厂模式:定义了一个用于创建对象的接口(工厂),让其具体的工厂子类决定实例化哪个类:使得一个类的实例化延迟到其子类;适用于创建的对象比较少的情况

    image-20240205192704328

  • 抽象工厂:定义了一个工厂创作器(用于创建指定的工厂,里面包含多个工厂),进而通过该工厂创建具体的产品

访问类提供一个创建一组相关或相互依赖对象的接口,且==访问类无须指定所要产品的具体类==就能得到同族的不同等级的产品的模式结构;

image-20240205192704328

相关推荐

  1. 开始设计模式_工厂模式

    2024-02-06 22:42:01       29 阅读
  2. 设计模式工厂模式抽象工厂模式区别

    2024-02-06 22:42:01       10 阅读
  3. 开始设计模式_适配器模式

    2024-02-06 22:42:01       31 阅读
  4. 设计模式工厂模式抽象工厂模式

    2024-02-06 22:42:01       24 阅读
  5. 设计模式 抽象工厂

    2024-02-06 22:42:01       23 阅读
  6. 设计模式抽象工厂

    2024-02-06 22:42:01       26 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-06 22:42:01       14 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-06 22:42:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-06 22:42:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-06 22:42:01       18 阅读

热门阅读

  1. C#面:final ,finally,finalize 的区别

    2024-02-06 22:42:01       29 阅读
  2. Z0423 树的染色2

    2024-02-06 22:42:01       29 阅读
  3. 详解MYSQL中的平均值组大小

    2024-02-06 22:42:01       25 阅读
  4. 前端开发:入门(一)

    2024-02-06 22:42:01       23 阅读
  5. 记录 | .ui转.py

    2024-02-06 22:42:01       26 阅读
  6. 23种设计模式之工厂模式

    2024-02-06 22:42:01       30 阅读
  7. 设计模式(结构型模式)桥接模式

    2024-02-06 22:42:01       27 阅读
  8. Vue 插槽的基本用法

    2024-02-06 22:42:01       29 阅读
  9. MySQL深入——18

    2024-02-06 22:42:01       27 阅读