抽象工厂模式 (Abstract Factory Pattern)

定义:

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种方式来封装一组具有共同主题的单个工厂,而无需指定它们的具体类。这种模式用于生成一系列相关或依赖对象的接口,而不指定它们具体的类。

抽象工厂模式通常涉及以下几个角色:

  1. 抽象工厂(Abstract Factory) :
    • 定义用于创建一系列相关或相互依赖对象的接口,但不具体指定这些对象的具体类。
  2. 具体工厂(Concrete Factory) :
    • 实现抽象工厂的接口,具体化创建相应的产品对象。
  3. 抽象产品(Abstract Product) :
    • 为一系列具体产品定义接口。
  4. 具体产品(Concrete Product) :
    • 抽象产品的具体实现,由具体工厂创建。
  5. 客户端(Client) :
    • 仅使用由抽象工厂和抽象产品提供的接口来创建一系列相关或依赖的对象。
解决的问题:
  • 支持产品族的创建 :
    • 当需要创建一组相关或相互依赖的对象时,抽象工厂模式使你可以一次性创建所有相关对象,而不是分别创建。这确保了产品族内的对象是兼容的,并一起协同工作。
  • 解耦产品的具体实现与客户代码 :
    • 抽象工厂模式使客户端代码从具体产品的实现中解耦出来,客户端只依赖于产品的抽象接口。具体产品的实现是由工厂的具体子类来完成的,客户端不需要知道这些细节。
  • 易于交换产品系列 :
    • 由于工厂本身创建了所有的产品实例,所以更换产品族变得容易。更换不同的工厂可以生成不同的产品对象,而客户端代码几乎不需要做出改变。
  • 增强一致性 :
    • 当一组对象需要协同工作时,抽象工厂确保客户端始终只使用同一产品族中的对象,这有助于防止与特定产品族不兼容的对象的使用。
  • 支持可扩展性和动态性 :
    • 抽象工厂模式支持添加新的具体工厂和产品类,而不需要修改现有的代码。这符合开闭原则,对于扩展是开放的,对于修改是封闭的。
使用场景:
  • 产品族的创建 :
    • 当系统需要创建一系列相关或依赖的对象时,尤其是这些对象构成一个产品族,且需要确保客户端只使用同一个产品族中的对象。
  • 系统配置与产品类型 :
    • 当系统需要被配置为多种不同的环境之一时,每种环境都需要不同的对象组合。抽象工厂允许动态地更改系统的配置,以使用不同的产品组合。
  • 强调一致性 :
    • 当强调一系列相关的产品对象设计以保持一致性时,而不是强调单个产品对象。
  • 封装多个系列 :
    • 当需要封装多个系列中的产品创建逻辑,以隐藏具体实现并暴露统一的接口给客户端。
  • 提供产品库的访问 :
    • 当系统需要提供一个产品库,客户端不需要知道从库中获取对象的逻辑,只需通过抽象的接口访问即可。
  • 运行时切换产品系列 :
    • 当需要在运行时切换不同的产品系列时,抽象工厂允许不改变客户端代码的前提下实现这一点。
示例代码:
java 复制代码
// 抽象产品
public interface AbstractProductA {
    void useA();
}

public interface AbstractProductB {
    void useB();
}

// 具体产品
public class ProductA1 implements AbstractProductA {
    @Override
    public void useA() {
        System.out.println("Using ProductA1");
    }
}

public class ProductB1 implements AbstractProductB {
    @Override
    public void useB() {
        System.out.println("Using ProductB1");
    }
}

public class ProductA2 implements AbstractProductA {
    @Override
    public void useA() {
        System.out.println("Using ProductA2");
    }
}

public class ProductB2 implements AbstractProductB {
    @Override
    public void useB() {
        System.out.println("Using ProductB2");
    }
}

// 抽象工厂
public interface AbstractFactory {
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}

// 具体工厂
public class ConcreteFactory1 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB1();
    }
}

public class ConcreteFactory2 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB2();
    }
}
主要符合的设计原则:
  1. 开闭原则(Open-Closed Principle) :
    • 抽象工厂模式很好地符合开闭原则。它允许在不修改现有代码的情况下引入新的工厂和产品族。当需要添加一个新的产品族时,只需创建新的具体工厂和一系列产品对象即可。
  2. 单一职责原则(Single Responsibility Principle) :
    • 每个具体工厂类只负责创建特定的产品对象,遵循了单一职责原则。这样的设计使得工厂职责明确,同时简化了客户端与具体产品的交互。
  3. 依赖倒转原则(Dependency Inversion Principle) :
    • 在抽象工厂模式中,客户代码依赖于抽象而不是具体的实现。这意味着客户代码通过抽象工厂和产品接口与具体的产品实例交互,而不需要关心这些产品的具体类。
  4. 接口隔离原则(Interface Segregation Principle) :
    • 抽象工厂模式提供了一组接口,每个接口对应创建一种特定类型的产品。这符合接口隔离原则,因为客户端只需要关心它使用的那些接口,不必关心与之无关的接口。

抽象工厂模式通过提供一组接口来创建一系列相关或相互依赖的对象,而无需指定它们的具体类。这种模式支持高度的模块化,使得添加新产品族变得简单,同时保持客户代码与具体实现的解耦。

在JDK中的应用:
  • Java数据库连接(JDBC) :
    • JDBC提供了一个很好的抽象工厂模式例子。java.sql.Connection、java.sql.Statement、java.sql.ResultSet 等接口的实现通常由数据库驱动提供。这里,java.sql.DriverManager 获取到 Connection 对象的过程,实际上是使用了某个特定数据库驱动的工厂方法,这个过程隐藏了不同数据库驱动之间的差异。
  • Java XML API :
    • 在处理XML时,Java的 javax.xml.parsers.DocumentBuilderFactory 和 javax.xml.transform.TransformerFactory 等类为不同的XML解析器和转换器实现提供了工厂接口。这些工厂类根据环境配置或系统属性返回特定实现的实例。
  • Java加密技术(JCE) :
    • Java加密扩展(JCE)框架使用工厂方法提供了加密算法的实现。例如,javax.crypto.KeyGenerator 和 javax.crypto.Cipher 类根据指定的算法名称返回特定算法的实现。
在Spring中的应用:
  • BeanFactory 和 ApplicationContext :
    • 在Spring中,BeanFactory 提供了一个高级的配置机制,用于管理任何类型的对象。ApplicationContext 是 BeanFactory 的子接口,它添加了更多的企业特定的功能。这些都可以看作是抽象工厂,提供了创建和管理bean的机制。
  • FactoryBean :
    • Spring中的 FactoryBean 是一个接口,用户可以通过实现这个接口来创建复杂的bean。这个接口充当了抽象工厂,而实现了 FactoryBean 的类则相当于具体工厂,负责创建特定类型的对象。
  • 多个数据源的配置 :
    • 当应用程序需要连接到多个数据库时,Spring允许配置多个数据源。每个数据源的配置可以视为一个具体工厂,创建特定于数据库类型的连接。
  • Spring中的模板类 :
    • 例如 JdbcTemplate, JmsTemplate, RestTemplate 等,这些模板类提供了与不同类型的技术进行交互的高层封装。它们背后的实现(如数据库访问技术、消息服务、REST客户端等)可以看作是通过不同的工厂创建的。

相关推荐
JAVA面经实录9172 分钟前
Java高级后端 · 全套面试通关手册(MySQL)
java·mysql·面试
言乐614 分钟前
Python实现关税自动计算模型
开发语言·python·django·virtualenv·pygame
朝朝辞暮i14 分钟前
C++ 第 14 课:引用 &
开发语言·c++·算法
光依旧16 分钟前
MCP实战手记(八):从“能跑“到“能上线“——无状态MCP Server的生产落地清单
java·人工智能·spring boot·架构·ai agent·mcp
梅雅达编程笔记42 分钟前
04-Python CSV数据保存与翻页抓取
开发语言·爬虫·python·pandas·数据采集·csv
C++ 老炮儿的技术栈1 小时前
有符号变量与无符号变量的区别
服务器·开发语言·前端·数据结构·c++·算法·c
估值探索者1 小时前
【Python量化策略实战 #04】Donchian 通道假突破太多?用 ATR 阈值过滤跑通真实突破信号
开发语言·python·接口·api接口·数据api接口·股票数据api接口
个 人 练 习 生1 小时前
C++:模板初阶详解
开发语言·c++·经验分享·学习
知识分享小能手1 小时前
C++ 学习教程,从入门到精通,C++类继承 — 完整知识点详解(13)
开发语言·c++·学习
弹简特1 小时前
【Java项目-企悦抽】15-活动管理模块02-活动创建测试与活动列表实现
java·开发语言·springboot