设计模式-工厂模式

简单工厂

通过 一个工厂类 根据参数创建不同产品。

  1. 定义产品接口
java 复制代码
package com.zr.factory.simpleFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/13:52
 * @Description:
 */
// 产品接口
public interface Product {
    void show();
}
  1. 定义产品A,实现产品接口,并且实现接口对应方法
java 复制代码
package com.zr.factory.simpleFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/13:52
 * @Description:
 */
// 产品A
public class ProductA implements Product{
    @Override
    public void show() {
        System.out.println("这是 ProductA");
    }
}
  1. 定义产品B,实现产品接口,并且实现接口对应方法
java 复制代码
package com.zr.factory.simpleFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/13:53
 * @Description:
 */
// 产品B
public class ProductB implements Product{
    @Override
    public void show() {
        System.out.println("这是 ProductB");
    }
}
  1. 定义简单工厂,定义一个可以根据不同入参type,产出不同产品的方法
java 复制代码
package com.zr.factory.simpleFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/13:55
 * @Description:
 */
// 简单工厂
public class SimpleFactory {
    // 定义方法根据不同type创建对应类型产品
    public Product createProduct(String type){
        switch ( type){
            case "A":
                return new ProductA();
            case "B":
                return new ProductB();
            default:
                throw new RuntimeException("没有此产品");
        }
    }
    // 测试创建不同产品调用相同方法,但是显示不同
    public static void main(String[] args) {
        Product productA = new SimpleFactory().createProduct("A");
        productA.show();
        Product productB = new SimpleFactory().createProduct("B");
        productB.show();
        Product productC = new SimpleFactory().createProduct("C");
        productC.show();
    }
}
  1. 测试结果

工厂方法

将创建对象的过程交给子类工厂实现

相比于简单工厂更加灵活,符合开闭原则

  1. Product接口,ProductA类,ProductB类和简单工厂是一样的,这里我就不贴重复代码了,代码结构如下
  1. 定义一个工厂接口,并且定义一个createProduct方法用于创建产品
java 复制代码
package com.zr.factory.factoryMethod;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:17
 * @Description:
 */
public interface Factory {
    Product createProduct();
}
  1. 定义一个AFactory类,实现Factory接口,并且重写createProduct方法,用于创建产品A
java 复制代码
package com.zr.factory.factoryMethod;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:17
 * @Description:
 */
public class AFactory implements  Factory{
    @Override
    public Product createProduct() {
        return new ProductA();
    }
}
  1. 定义一个BFactory类,实现Factory接口,并且重写createProduct方法,用于创建产品B
java 复制代码
package com.zr.factory.factoryMethod;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:17
 * @Description:
 */
public class BFactory implements  Factory {
    @Override
    public Product createProduct() {
        return new ProductB();
    }
}
  1. 测试
java 复制代码
package com.zr.factory.factoryMethod;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:18
 * @Description:
 */
public class TestFactoryMethod {
    public static void main(String[] args) {
        Product productA = new AFactory().createProduct();
        productA.show();
        Product productB = new BFactory().createProduct();
        productB.show();
    }
}
  1. 测试结果

抽象工厂

生产一组相关/成套的产品(比如不同品牌的手机、电脑、耳机)。

常用于大型系统里的"多系列产品"。
适用场景

  • 产品成套生产(如 小米系手机+平板 / 苹果系手机+平板)
  • 一个工厂生产多个相关对象
  1. 定义一个Phone接口,定义call方法
java 复制代码
package com.zr.factory.abstractFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:27
 * @Description:
 */
public interface Phone {
    void call();
}
  1. 定义一个Laptop接口,定义work方法
java 复制代码
package com.zr.factory.abstractFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:27
 * @Description:
 */
public interface Laptop {
    void work();
}
  1. 定义一个XiaomiPhone类,实现Phone接口,并且重写call方法
java 复制代码
package com.zr.factory.abstractFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:27
 * @Description:
 */
public class XiaomiPhone implements  Phone{
    @Override
    public void call() {
        System.out.println("call方法使用 Xiaomi Phone");
    }
}
  1. 定义一个ApplePhone类,实现Phone接口,并且重写call方法
java 复制代码
package com.zr.factory.abstractFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:29
 * @Description:
 */
public class ApplePhone implements  Phone{
    @Override
    public void call() {
        System.out.println("call方法使用 Apple Phone");
    }
}
  1. 定义一个XiaomiLaptop类,实现Laptop接口,并且重写work方法
java 复制代码
package com.zr.factory.abstractFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:28
 * @Description:
 */
public class XiaomiLaptop implements Laptop{
    @Override
    public void work() {
        System.out.println("work方法使用 Xiaomi Laptop");
    }
}
  1. 定义一个AppleLaptop类,实现Laptop接口,并且重写work方法
java 复制代码
package com.zr.factory.abstractFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:29
 * @Description:
 */
public class AppleLaptop implements Laptop{
    @Override
    public void work() {
        System.out.println("work方法使用 Apple Laptop");
    }
}
  1. 定义一个ElectronicsFactory电子产品工厂接口,并且定义一个createPhone方法用于电子产品手机,和createLaptop方法用于电子产品平板
java 复制代码
package com.zr.factory.abstractFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:30
 * @Description:
 */
public interface ElectronicsFactory {
    Phone createPhone();

    Laptop createLaptop();
}
  1. 测试
java 复制代码
package com.zr.factory.abstractFactory;

/**
 * @Author: zr
 * @Date: 2025/11/05/14:32
 * @Description:
 */
public class TestAbstractFactory {
    public static void main(String[] args) {
        ElectronicsFactory factory = new AppleFactory();
        Phone phone = factory.createPhone();
        Laptop laptop = factory.createLaptop();
        phone.call();
        laptop.work();
    }
}
  1. 测试结果

Spring中使用到的工厂模式

✅ 1. BeanFactory + 其子工厂(最标准的抽象工厂)

BeanFactory抽象工厂

→ 定义"创建 Bean"的抽象方法。

具体工厂实现:

  • DefaultListableBeanFactory
  • XmlBeanFactory(旧版本)
  • AnnotationConfigApplicationContext(内部也是 beanFactory)

抽象工厂结构

java 复制代码
public interface BeanFactory {
    Object getBean(String name);
}

具体工厂实现

java 复制代码
public class DefaultListableBeanFactory implements BeanFactory {
    // createBean / getBean 内部负责实例化、依赖注入
}

BeanFactory 是抽象工厂,能够创建任意 bean

✅ 每个具体 BeanFactory 都是一个工厂实现

✅ Bean 就是"产品族",Spring 管理所有 bean 的实例化


✅ 2. ApplicationContext 同样是抽象工厂(更强大的工厂)

ApplicationContext 继承 BeanFactory,同时扩展出多产品族功能:

java 复制代码
public interface ApplicationContext extends EnvironmentCapable,
                                            ListableBeanFactory,
                                            HierarchicalBeanFactory,
                                            MessageSource,
                                            ApplicationEventPublisher,
                                            ResourcePatternResolver {
}

一个 ApplicationContext 工厂可以创建:

  • Bean(产品) ✅
  • 国际化 MessageSource(产品) ✅
  • ApplicationEventPublisher(产品) ✅
  • Environment(产品) ✅
  • ResourceLoader(产品) ✅

典型的抽象工厂:一个工厂生产一系列(产品族)相关对象

具体的工厂实现:

  • ClassPathXmlApplicationContext
  • AnnotationConfigApplicationContext
  • FileSystemXmlApplicationContext

✅ 3. FactoryBean(小型抽象工厂)

FactoryBean 是 Spring 中非常典型的小型抽象工厂模式。

结构

java 复制代码
public interface FactoryBean<T> {
    T getObject() throws Exception;   // 工厂创建产品
    Class<?> getObjectType();
}

使用场景:

  • MyBatis 的 MapperFactoryBean
  • ProxyFactoryBean
  • 创建动态代理
  • 创建复杂对象(如 SqlSessionFactory)

✅ 每个 FactoryBean 都是一个"工厂",它让开发者自己"定制生产某个 bean"


✅ 4. BeanDefinitionReader(抽象工厂 + 工厂方法)

Spring 读取配置文件的时候用到:

  • XmlBeanDefinitionReader
  • PropertiesBeanDefinitionReader
  • AnnotatedBeanDefinitionReader

这些 Reader 负责"生产 BeanDefinition 对象",也是一种抽象工厂。


✅ 5. AOP 相关:AdvisorFactory / ProxyFactory

Spring AOP 动态代理也用了多处抽象工厂:

  • AdvisorAdapterRegistry
  • AopProxyFactory
  • DefaultAopProxyFactory

例如:

java 复制代码
public interface AopProxyFactory {
    AopProxy createAopProxy(AdvisedSupport config);
}

不同的工厂创建不同代理实现:

  • JdkDynamicAopProxy
  • ObjenesisCglibAopProxy

这也是典型抽象工厂:创建一系列相关代理对象


✅ 6. 后处理器(BeanPostProcessor)链路中的工厂

InstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor

这些类负责 扩展 Bean 创建逻辑,形成一个"产品族创建体系"。


✅ Spring工厂模式总结

Spring 中最典型的抽象工厂实现:

抽象工厂接口 具体工厂实现 产品族
BeanFactory DefaultListableBeanFactory Bean 实例
ApplicationContext AnnotationConfigApplicationContext Bean + Environment + MessageSource + 事件发布器等
FactoryBean MapperFactoryBean / ProxyFactoryBean 特殊 bean(代理、SqlSessionFactory 等)
AopProxyFactory DefaultAopProxyFactory AOP 代理对象
BeanDefinitionReader XmlBeanDefinitionReader BeanDefinition(用于构建 bean)

✅ Spring 大量用"抽象工厂 + 工厂方法 + 模板方法"

✅ 这些共同构成 Spring IOC 的核心创建体系


总结

对比表

模式 特点 使用难度 常用程度
简单工厂 写一个工厂,所有产品都从这里创建 ★☆☆ 常用
工厂方法 一个产品一个工厂,更灵活,可扩展 ★★☆ 非常常用
抽象工厂 创建"产品族",大型系统用( 一整个系列的产品由同一个工厂生产 ) ★★★ 框架级常用(如 Spring)

✅ 一、这三个到底解决什么问题?

模式 解决的问题
简单工厂 由一个工厂根据参数决定创建哪种产品 ------ 用"一个类"创建多个同类产品
工厂方法 把"创建工作"交给子类,每个工厂只负责创建一种产品 ------ 让创建更可扩展
抽象工厂 一个工厂可以创建"同一系列多个产品" ------ 产品族创建(成套餐具)

✅ 二、结构区别(简单到复杂顺序)

✅ 1. 简单工厂:一个工厂 → 多个具体产品

plain 复制代码
SimpleFactory
    ├── create("A") → ProductA
    └── create("B") → ProductB

特点:

  • 工厂很"全能"
  • 但不符合开闭原则(新增产品要改工厂)

使用场景:

✅ 产品类型少

✅ 产品变化不频繁

✅ 就想简单省事


✅ 2. 工厂方法:多个工厂 → 一个具体产品

plain 复制代码
Factory (接口)
    ├── AFactory → ProductA
    └── BFactory → ProductB

特点:

  • 一个产品一个工厂
  • 更灵活
  • 新增产品不需要改旧工厂

使用场景:

✅ 产品类型多

✅ 产品经常扩展

✅ 想要遵守开闭原则


✅ 3. 抽象工厂:一个工厂 → 多个"同系列产品"

plain 复制代码
ElectronicsFactory
   ├── XiaomiFactory
   │       ├── createPhone() → 小米手机
   │       └── createLaptop() → 小米笔记本
   └── AppleFactory
           ├── createPhone() → iPhone
           └── createLaptop() → MacBook

特点:

  • 一次性创建一整套产品(产品族)
  • 工厂创建多个方法(多产品)

使用场景:

✅ 手机 + 电脑 + 平板属于"同一个品牌"

✅ 必须保持产品之间配套(同品牌不混搭)

✅ 大型框架开发(比如 Spring、JDBC 驱动等)


✅ 三、使用场景区别(最关键)

下面这一张表 面试必杀

模式 适用场景 举例
简单工厂 产品创建逻辑集中、不复杂 LoggerFactory、JDK DateFormat、工具类
工厂方法 每种产品要独立扩展 不同支付方式、不同解析器、不同数据库连接创建
抽象工厂 "产品族"必须成套出现 小米手机+电脑、苹果手机+电脑;GUI 主题一整套控件

一句话:

  • 简单工厂:同类产品不同版本
  • 工厂方法:单产品体系,可扩展
  • 抽象工厂:多产品族,一整套一起建

✅ 四、实际代码规模区别

模式 工厂数量 方法数量 代码复杂度
简单工厂 1 个 1~多个 ⭐ 最简单
工厂方法 n 个(=产品数) 每工厂 1 个 ⭐⭐ 适中
抽象工厂 n 个(=产品族数) 每工厂多个 ⭐⭐⭐ 最复杂
相关推荐
MATLAB代码顾问1 小时前
MATLAB实现决策树数值预测
开发语言·决策树·matlab
凌波粒2 小时前
MyBatis完整教程IDEA版(2)--ResultMap/注解/一对多/多对一/lombok/log4j
java·intellij-idea·mybatis
蓝-萧2 小时前
【玩转全栈】----Django基本配置和介绍
java·后端
priority_key2 小时前
排序算法:堆排序、快速排序、归并排序
java·后端·算法·排序算法·归并排序·堆排序·快速排序
不染尘.3 小时前
2025_11_7_刷题
开发语言·c++·vscode·算法
似水এ᭄往昔3 小时前
【C++】--stack和queue
开发语言·c++
csbysj20203 小时前
R 绘图 - 散点图
开发语言
汤姆yu3 小时前
基于SpringBoot的动漫周边商场系统的设计与开发
java·spring boot·后端
皮皮林5513 小时前
快速解决 Maven 版本冲突指南 !
java·maven