• 【一天一个设计模式】—— 抽象工厂模式


    定义:

    Provide an interface for creating families of related or dependent
    objects without specifying their concrete classes.

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

    和工厂模式一样,抽象工厂模式同样是创建型设计模式,但不同的是,抽象工厂中的每个工厂可以创建多种类的产品;而工厂方法每个工厂只能创建一类产品

    举个栗子,你有一家公司,名下有一座生产矿泉水的工厂,它可以根据传入的订单号生产不同价位的矿泉水,这就是工厂模式,只能创建矿泉水一类产品。由于业务拓展,你想生产饮料类产品,经过协商,你建造了一个可以同时容纳矿泉水工厂和饮料工厂的超大工厂,而矿泉水工厂和饮料工厂又可以根据需求生产价位不同的饮品,这就是抽象工厂模式,抽象工厂中每个工厂可以创建多种类的产品。


    下面通过RUNOOB中的例子来详细分析抽象工厂模式(简化形式,无AbstractProduct类)。
    在这里插入图片描述
    通过UML图可以很清晰的分析出抽象工厂模式的组成包括工厂生成器、抽象工厂类、工厂类、产品接口、产品接口实现类。下面通过代码分析。


    代码

    产品接口 – shape

    public interface Shape {
       void draw();
    }
    ------------------------
    public interface Color {
       void fill();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    产品接口shape实现类 – Rectangle、Square、Circle

    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.");
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    产品接口color实现类 – Red 、Green 、Blue

    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.");
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    抽象工厂类AbstractFactory

    public abstract class AbstractFactory {
       public abstract Color getColor(String color);
       public abstract Shape getShape(String shape);
    }
    
    • 1
    • 2
    • 3
    • 4

    来看抽象工厂类,其中定义了两个抽象方法getColor()、getShape(),接下来我们就要扩展这两个抽象方法,即创建工厂类来继承抽象工厂类,根据条件生成具体的产品。

    工厂类ShapeFactory

    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;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    工厂类ColorFactory

    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;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    工厂生成器

    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;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    该类的作用是根据传入的条件创建具体工厂。

    以上即是抽象工厂模式的大致结构,要想获取具体对象,先通过FactoryProducer类中的getFactory()获取AbstractFactory,再通过传入相应条件来获取实体类对象。


    扩展:

    1.在抽象工厂模式中,假设我们需要增加一个工厂(事实上是增加了产品和工厂),那该怎么做呢?

    在如上代码中,假设我们要增加一个材质工厂MaterialFactory,第一步需要生成Material接口,并创建其实现类,即具体产品(Glass,Iron,Wood),第二步,在抽象工厂类中创建新的抽象方法getMaterial(),第三步,创建工厂类MaterialFactory,重写其抽象方法getMaterial(),第四步,在工厂生成器中增加判断条件。

    当然若我们的结构是这样的话:即工厂类中的产品来自不同类(看UML图)
    在这里插入图片描述
    上图中,产品接口的父类是一个抽象类。
    在这里插入图片描述
    增加一个工厂(产品族)只需:
    在这里插入图片描述
    而增加一个新的产品(新的产品种类)需要:
    在这里插入图片描述
    这里修改了抽象类及其子类,违背了开闭原则。

    2.它体现了设计模式中什么原则?

    符合开闭原则单一职责原则

    3.它的缺点是什么?

    当增加一个新的产品种类时,此时就必须去修改抽象工厂,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

  • 相关阅读:
    springboot 配置文件编写 自定义参数 配置提示功能 配置处理器
    SPA项目开发之动态树+数据表格+分页
    5-VMware Horizon 2203 虚拟桌面-Connect注册服务器(五)
    性能测试工具——Jmeter的安装【超详细】
    spring cloud笔记--微服务基础
    SpringCloud微服务:Nacos的下载和配置
    基于Java毕业设计志愿者管理系统演示录像2020源码+系统+mysql+lw文档+部署软件
    jupyter notebook代码自动换行,超过一行长度自动换行,不用左右滑动
    Spark性能调优案例-多表join优化,减少shuffle
    基于JAVA学生招生信息网计算机毕业设计源码+系统+mysql数据库+lw文档+部署
  • 原文地址:https://blog.csdn.net/intwei/article/details/125623563