工厂模式
问题
什么是工厂模式?简单工厂、工厂方法、抽象工厂有什么区别?
答案
三种工厂模式对比
| 模式 | 核心思想 | 新增产品 | 复杂度 |
|---|---|---|---|
| 简单工厂 | 一个工厂类,根据参数创建不同产品 | 修改工厂类(违反开闭原则) | 低 |
| 工厂方法 | 每个产品对应一个工厂类 | 新增工厂类(符合开闭原则) | 中 |
| 抽象工厂 | 一个工厂创建一组相关产品(产品族) | 新增产品族加工厂;新增产品类型要改接口 | 高 |
简单工厂
简单工厂 - 根据类型创建对象
public class PaymentFactory {
public static Payment create(String type) {
switch (type) {
case "alipay": return new AlipayPayment();
case "wechat": return new WechatPayment();
default: throw new IllegalArgumentException("不支持的支付类型: " + type);
}
}
}
// 使用
Payment payment = PaymentFactory.create("alipay");
payment.pay(100);
缺点
每新增一种支付方式都要修改 PaymentFactory,违反开闭原则(对扩展开放、对修改关闭)。
工厂方法
每个产品对应一个工厂,新增产品只需新增工厂类。
工厂方法 - 每个产品一个工厂
// 工厂接口
public interface PaymentFactory {
Payment create();
}
// 具体工厂
public class AlipayFactory implements PaymentFactory {
@Override
public Payment create() {
return new AlipayPayment();
}
}
public class WechatFactory implements PaymentFactory {
@Override
public Payment create() {
return new WechatPayment();
}
}
// 新增银联支付:只需新增 UnionPayFactory,不修改已有代码
抽象工厂
创建一组相关产品(产品族),如不同数据库的 Connection + Statement + ResultSet。
抽象工厂 - 创建产品族
// 抽象工厂:定义一组产品的创建
public interface DatabaseFactory {
Connection createConnection();
Statement createStatement();
}
// MySQL 产品族
public class MySQLFactory implements DatabaseFactory {
@Override
public Connection createConnection() { return new MySQLConnection(); }
@Override
public Statement createStatement() { return new MySQLStatement(); }
}
// PostgreSQL 产品族
public class PostgreSQLFactory implements DatabaseFactory {
@Override
public Connection createConnection() { return new PostgreSQLConnection(); }
@Override
public Statement createStatement() { return new PostgreSQLStatement(); }
}
Spring 中的工厂模式
| 应用场景 | 说明 |
|---|---|
BeanFactory | IoC 容器本身就是一个大工厂 |
FactoryBean | 自定义 Bean 的创建逻辑 |
ObjectFactory | 延迟创建 Bean(三级缓存) |
FactoryBean 自定义创建逻辑
@Component
public class ConnectionFactoryBean implements FactoryBean<Connection> {
@Override
public Connection getObject() throws Exception {
return DriverManager.getConnection("jdbc:mysql://localhost/db");
}
@Override
public Class<?> getObjectType() {
return Connection.class;
}
}
常见面试问题
Q1: 简单工厂和工厂方法的区别?
答案:
- 简单工厂:一个工厂类 + switch/if 创建所有产品,新增产品需修改工厂
- 工厂方法:每个产品一个工厂类,新增产品只需新增工厂,符合开闭原则
- 项目中产品类型较少且稳定时用简单工厂即可;频繁扩展时用工厂方法
Q2: Spring 中的 BeanFactory 和 FactoryBean 区别?
答案:
BeanFactory:Spring IoC 容器的根接口,负责管理和创建所有 BeanFactoryBean:一个特殊的 Bean,实现后可以自定义某个 Bean 的创建逻辑。getBean("name")返回 FactoryBean 创建的对象,getBean("&name")返回 FactoryBean 本身
详见 Spring IoC。
Q3: 工厂模式在实际项目中的应用?
答案:
- 支付方式:根据配置创建不同支付渠道实现
- 日志框架:
LoggerFactory.getLogger()创建不同日志实现 - 数据源:根据环境创建不同数据库连接
- 序列化:根据格式创建 JSON/XML/Protobuf 序列化器