文章目录
- 前言
- 一、概念
- 二、核心思想
- 三、Java代码实现
-
- [1. 定义抽象产品(产品族的两个核心接口)](#1. 定义抽象产品(产品族的两个核心接口))
- [2. 定义具体产品(MySQL/Oracle产品族)](#2. 定义具体产品(MySQL/Oracle产品族))
- [3. 定义抽象工厂(数据库组件工厂接口)](#3. 定义抽象工厂(数据库组件工厂接口))
- [4. 定义具体工厂(MySQL/Oracle工厂)](#4. 定义具体工厂(MySQL/Oracle工厂))
- [5. 客户端使用代码](#5. 客户端使用代码)
- [6. 扩展:新增PostgreSQL产品族(符合开闭原则)](#6. 扩展:新增PostgreSQL产品族(符合开闭原则))
- 四、优缺点
-
- [1. 优点](#1. 优点)
- [2. 缺点](#2. 缺点)
- 五、应用场景
- 六、注意事项
- 总结
前言
在AI时代,代码的编写可以被大模型辅助甚至替代,但程序员真正的核心竞争力是技术思维------设计模式这类沉淀了数十年的"内功心法",决定了代码的可维护性、扩展性和稳定性,是AI无法完全替代的核心能力。抽象工厂模式作为创建型模式的进阶版本,解决了"一组相关产品族创建"的问题,是应对复杂产品体系的核心设计思路。
一、概念
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,核心目标是提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它将"产品族"的创建逻辑封装在抽象工厂中,客户端通过抽象工厂获取整个产品族的实例,而非单个产品。
简单来说,若把工厂方法模式看作"生产单一产品的工厂",抽象工厂模式就是"生产整套产品的工厂"------比如一个"家具工厂"不仅能生产椅子,还能生产桌子、沙发,且不同工厂(中式家具厂、欧式家具厂)生产的是配套的产品族。
二、核心思想
- 抽象产品族:将一组相关的产品抽象为多个接口(如椅子、桌子、沙发),每个接口代表一类产品;
- 具体产品族:实现抽象产品接口,且同一产品族的具体产品需配套(如中式椅子、中式桌子、中式沙发);
- 抽象工厂:定义创建整个产品族的抽象方法,每个方法对应一类产品的创建(如创建椅子、创建桌子);
- 具体工厂:实现抽象工厂的所有方法,返回同一产品族的具体产品实例(如中式家具厂创建中式椅子、中式桌子)。
抽象工厂模式的核心本质是产品族的封装与解耦------客户端只需依赖抽象工厂和抽象产品,无需关心具体产品的实现,新增产品族时只需新增"具体工厂+对应产品族",符合开闭原则。
三、Java代码实现
以"数据库访问组件"场景为例:系统需支持MySQL和Oracle两种数据库,每种数据库都包含Connection(连接)和Statement(语句)两个配套产品,用抽象工厂模式实现不同数据库产品族的创建。
1. 定义抽象产品(产品族的两个核心接口)
java
/**
* 抽象产品1:数据库连接接口
* 定义数据库连接的通用行为
*/
public interface DBConnection {
// 建立连接
void connect();
}
/**
* 抽象产品2:数据库语句接口
* 定义数据库语句的通用行为
*/
public interface DBStatement {
// 执行SQL
void execute(String sql);
}
2. 定义具体产品(MySQL/Oracle产品族)
java
/**
* 具体产品1:MySQL数据库连接
*/
public class MySQLConnection implements DBConnection {
@Override
public void connect() {
System.out.println("建立MySQL数据库连接");
}
}
/**
* 具体产品2:MySQL数据库语句
*/
public class MySQLStatement implements DBStatement {
@Override
public void execute(String sql) {
System.out.println("MySQL执行SQL:" + sql);
}
}
/**
* 具体产品3:Oracle数据库连接
*/
public class OracleConnection implements DBConnection {
@Override
public void connect() {
System.out.println("建立Oracle数据库连接");
}
}
/**
* 具体产品4:Oracle数据库语句
*/
public class OracleStatement implements DBStatement {
@Override
public void execute(String sql) {
System.out.println("Oracle执行SQL:" + sql);
}
}
3. 定义抽象工厂(数据库组件工厂接口)
java
/**
* 抽象工厂:数据库组件工厂接口
* 定义创建数据库产品族的抽象方法
*/
public interface DBFactory {
// 创建数据库连接
DBConnection createConnection();
// 创建数据库语句
DBStatement createStatement();
}
4. 定义具体工厂(MySQL/Oracle工厂)
java
/**
* 具体工厂1:MySQL组件工厂
* 负责创建MySQL产品族的所有产品
*/
public class MySQLFactory implements DBFactory {
@Override
public DBConnection createConnection() {
return new MySQLConnection();
}
@Override
public DBStatement createStatement() {
return new MySQLStatement();
}
}
/**
* 具体工厂2:Oracle组件工厂
* 负责创建Oracle产品族的所有产品
*/
public class OracleFactory implements DBFactory {
@Override
public DBConnection createConnection() {
return new OracleConnection();
}
@Override
public DBStatement createStatement() {
return new OracleStatement();
}
}
5. 客户端使用代码
java
/**
* 客户端:数据库操作层
* 只依赖抽象工厂和抽象产品,无需关心具体数据库类型
*/
public class Client {
public static void main(String[] args) {
// 1. 使用MySQL产品族
DBFactory mysqlFactory = new MySQLFactory();
DBConnection mysqlConn = mysqlFactory.createConnection();
DBStatement mysqlStmt = mysqlFactory.createStatement();
mysqlConn.connect();
mysqlStmt.execute("SELECT * FROM user");
// 2. 使用Oracle产品族
DBFactory oracleFactory = new OracleFactory();
DBConnection oracleConn = oracleFactory.createConnection();
DBStatement oracleStmt = oracleFactory.createStatement();
oracleConn.connect();
oracleStmt.execute("SELECT * FROM user");
}
}
输出结果:
建立MySQL数据库连接
MySQL执行SQL:SELECT * FROM user
建立Oracle数据库连接
Oracle执行SQL:SELECT * FROM user
6. 扩展:新增PostgreSQL产品族(符合开闭原则)
java
// 1. 新增PostgreSQL产品族的具体产品
public class PostgreSQLConnection implements DBConnection {
@Override
public void connect() {
System.out.println("建立PostgreSQL数据库连接");
}
}
public class PostgreSQLStatement implements DBStatement {
@Override
public void execute(String sql) {
System.out.println("PostgreSQL执行SQL:" + sql);
}
}
// 2. 新增PostgreSQL工厂
public class PostgreSQLFactory implements DBFactory {
@Override
public DBConnection createConnection() {
return new PostgreSQLConnection();
}
@Override
public DBStatement createStatement() {
return new PostgreSQLStatement();
}
}
// 3. 客户端使用(无需修改原有代码)
public class Client {
public static void main(String[] args) {
DBFactory pgFactory = new PostgreSQLFactory();
DBConnection pgConn = pgFactory.createConnection();
DBStatement pgStmt = pgFactory.createStatement();
pgConn.connect();
pgStmt.execute("SELECT * FROM user");
}
}
四、优缺点
1. 优点
- 产品族一致性:确保同一工厂创建的产品都是配套的(如MySQL连接+MySQL语句),避免出现"MySQL连接+Oracle语句"的不兼容情况;
- 解耦产品创建与使用:客户端仅依赖抽象层,无需知道具体产品的实现细节,降低代码耦合度;
- 符合开闭原则:新增产品族时,只需新增具体工厂和对应产品,无需修改原有代码;
- 简化客户端代码:客户端只需选择对应的工厂,即可获取整套产品,无需逐个创建产品。
2. 缺点
- 产品扩展困难:若需新增产品类型(如在数据库组件中新增"ResultSet"),需修改抽象工厂和所有具体工厂,违背开闭原则;
- 类数量膨胀:产品族和产品类型越多,系统中的类数量会呈指数级增长,增加维护成本;
- 抽象层设计复杂:需提前规划产品族的结构,抽象产品和抽象工厂的设计难度较高,若设计不合理,后续扩展会非常困难。
五、应用场景
抽象工厂模式适用于产品类型固定、但产品族易扩展的场景:
- 跨平台开发:如不同操作系统(Windows/Mac/Linux)的UI组件(按钮、输入框、下拉框),每个系统对应一个产品族;
- 数据库/中间件适配:如示例中的多数据库适配、不同消息队列(Kafka/RabbitMQ)的生产者/消费者配套创建;
- 框架底层设计 :Spring框架中的
BeanFactory(抽象工厂)创建不同类型的Bean产品族、MyBatis的数据源工厂; - 成套产品创建:如汽车制造(不同品牌的发动机+变速箱+底盘)、家具生产(中式/欧式/美式的椅子+桌子+沙发)。
六、注意事项
- 区分产品族和产品类型:产品族是"配套的一组产品"(如MySQL的连接+语句),产品类型是"同一类产品"(如所有数据库的连接),抽象工厂扩展产品族容易,扩展产品类型难;
- 避免过度设计:若产品类型少、产品族固定,使用工厂方法模式或简单工厂更简洁,无需引入抽象工厂;
- 结合工厂方法:可在抽象工厂的具体方法中结合工厂方法,将单个产品的创建逻辑进一步解耦;
- 与工厂方法的区别:工厂方法关注"单个产品的创建",抽象工厂关注"一组产品的创建";工厂方法只有一个抽象产品,抽象工厂有多个抽象产品。
总结
- 抽象工厂模式核心是创建配套的产品族,通过抽象工厂封装产品族的创建逻辑,保证产品一致性;
- 优势是产品族扩展灵活、客户端与具体产品解耦,缺点是产品类型扩展困难、类数量膨胀;
- 适用于"产品类型固定、产品族易变"的场景(如多数据库适配),是框架底层设计的常用模式。