一句话总结
工厂模式三种形态:简单工厂(一个工厂类根据参数创建不同产品,违反开闭原则)、工厂方法(每个产品对应一个工厂,符合开闭原则,但类数量膨胀)、抽象工厂(创建产品族,一组相关产品一起创建)。Spring 中 BeanFactory 是工厂方法模式的应用,FactoryBean 是自定义 Bean 创建逻辑的扩展点。
初级理解
简单工厂(Simple Factory)
# 产品接口
public interface Product {
void use();
}
# 具体产品
public class ProductA implements Product {
public void use() { System.out.println("使用产品A"); }
}
public class ProductB implements Product {
public void use() { System.out.println("使用产品B"); }
}
# 简单工厂
public class SimpleFactory {
public static Product create(String type) {
switch (type) {
case "A": return new ProductA();
case "B": return new ProductB();
default: throw new IllegalArgumentException("未知类型");
}
}
}
# 使用
Product p = SimpleFactory.create("A");
p.use();
# 缺点:新增产品需要修改工厂类(违反开闭原则)
工厂方法(Factory Method)
# 工厂接口
public interface Factory {
Product create();
}
# 具体工厂(每个产品一个工厂)
public class FactoryA implements Factory {
public Product create() { return new ProductA(); }
}
public class FactoryB implements Factory {
public Product create() { return new ProductB(); }
}
# 使用
Factory factory = new FactoryA();
Product p = factory.create();
p.use();
# 优点:新增产品只需新增工厂类(符合开闭原则)
# 缺点:类数量膨胀(每个产品都要一个工厂类)
中级深入
抽象工厂(Abstract Factory)
# 产品族:手机 + 耳机
public interface Phone { void call(); }
public interface Earphone { void listen(); }
# 华为产品族
public class HuaweiPhone implements Phone {
public void call() { System.out.println("华为手机打电话"); }
}
public class HuaweiEarphone implements Earphone {
public void listen() { System.out.println("华为耳机听音乐"); }
}
# 小米产品族
public class XiaomiPhone implements Phone {
public void call() { System.out.println("小米手机打电话"); }
}
public class XiaomiEarphone implements Earphone {
public void listen() { System.out.println("小米耳机听音乐"); }
}
# 抽象工厂(创建产品族)
public interface ElectronicsFactory {
Phone createPhone();
Earphone createEarphone();
}
# 华为工厂
public class HuaweiFactory implements ElectronicsFactory {
public Phone createPhone() { return new HuaweiPhone(); }
public Earphone createEarphone() { return new HuaweiEarphone(); }
}
# 小米工厂
public class XiaomiFactory implements ElectronicsFactory {
public Phone createPhone() { return new XiaomiPhone(); }
public Earphone createEarphone() { return new XiaomiEarphone(); }
}
# 使用:切换工厂即可切换整个产品族
ElectronicsFactory factory = new HuaweiFactory();
Phone phone = factory.createPhone();
Earphone earphone = factory.createEarphone();
三种工厂对比
| 维度 | 简单工厂 | 工厂方法 | 抽象工厂 |
|---|---|---|---|
| 产品数量 | 多个产品 | 一个产品等级 | 多个产品族 |
| 工厂数量 | 1个 | N个(每个产品一个) | M个(每个产品族一个) |
| 开闭原则 | 违反(需修改工厂) | 符合(新增工厂) | 符合(新增工厂) |
| 复杂度 | 低 | 中 | 高 |
高级进阶
Spring 中的工厂模式
# 1. BeanFactory(工厂方法模式)
# BeanFactory 是 Spring IoC 容器的顶层接口
public interface BeanFactory {
Object getBean(String name);
<T> T getBean(Class<T> requiredType);
<T> T getBean(String name, Class<T> requiredType);
}
# 实现类:DefaultListableBeanFactory
# 根据 beanName 返回对应的 Bean 实例
# 本质是工厂方法模式:每个 Bean 定义对应一个"产品"
# 2. FactoryBean(自定义 Bean 创建)
# 用于复杂 Bean 的创建(如 MyBatis 的 SqlSessionFactoryBean)
public interface FactoryBean<T> {
T getObject() throws Exception; // 返回 Bean 实例
Class<?> getObjectType(); // Bean 类型
default boolean isSingleton() { // 是否单例
return true;
}
}
# 示例:SqlSessionFactoryBean
public class SqlSessionFactoryBean implements
FactoryBean<SqlSessionFactory> {
@Override
public SqlSessionFactory getObject() throws Exception {
// 复杂的构建逻辑
return new SqlSessionFactoryBuilder()
.build(configuration);
}
}
# BeanFactory vs FactoryBean:
# BeanFactory:IoC 容器,管理所有 Bean(工厂方法模式)
# FactoryBean:自定义 Bean 创建逻辑的扩展点
# 获取 FactoryBean 本身:getBean("&beanName")
实战场景
# 场景1:支付渠道工厂
public interface PaymentService {
void pay(BigDecimal amount);
}
@Service("alipay")
public class AlipayService implements PaymentService {
public void pay(BigDecimal amount) { /* 支付宝支付 */ }
}
@Service("wechat")
public class WechatService implements PaymentService {
public void pay(BigDecimal amount) { /* 微信支付 */ }
}
@Component
public class PaymentFactory {
@Autowired
private Map<String, PaymentService> paymentMap;
public PaymentService getPayment(String channel) {
PaymentService service = paymentMap.get(channel);
if (service == null) {
throw new IllegalArgumentException("不支持的支付渠道");
}
return service;
}
}
# 场景2:策略+工厂组合(消除 if-else)
# 工厂负责创建策略对象,策略负责执行具体逻辑
面试模拟
面试官:简单工厂、工厂方法、抽象工厂的区别?
你:简单工厂一个工厂类创建所有产品,新增产品需修改工厂(违反开闭原则)。工厂方法每个产品对应一个工厂类,新增产品只需新增工厂(符合开闭原则),但类数量膨胀。抽象工厂创建产品族(一组相关产品),切换工厂即可切换整个产品族。简单工厂→工厂方法→抽象工厂,抽象程度递增。
面试官:Spring 中哪里用到了工厂模式?BeanFactory 和 FactoryBean 的区别?
你:BeanFactory 是工厂方法模式的应用,根据 beanName 返回 Bean 实例。FactoryBean 是自定义 Bean 创建逻辑的扩展点,用于复杂 Bean 的构建(如 SqlSessionFactoryBean)。BeanFactory 管理所有 Bean,FactoryBean 是 Bean 的一种特殊创建方式。获取 FactoryBean 本身用 getBean("&beanName")。