工厂模式?

2025年 阅读约 12 分钟 面试指南 · 设计模式

深入解析工厂模式三种形态:简单工厂、工厂方法、抽象工厂的区别与演进,开闭原则体现,Spring中BeanFactory和FactoryBean的应用,附面试模拟问答。

一句话总结

工厂模式三种形态:简单工厂(一个工厂类根据参数创建不同产品,违反开闭原则)、工厂方法(每个产品对应一个工厂,符合开闭原则,但类数量膨胀)、抽象工厂(创建产品族,一组相关产品一起创建)。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")。