Java设计模式实战:工厂模式,从“Hello World”到企业级架构的正确打开方式

目录

一、为什么我们需要工厂模式?

二、核心套路一:简单工厂 (Simple Factory)

[1. 定义与结构](#1. 定义与结构)

[2. Java代码实战](#2. Java代码实战)

[3. 优缺点分析](#3. 优缺点分析)

三、核心套路二:工厂方法 (Factory Method)

[1. 定义与结构](#1. 定义与结构)

[2. Java代码实战](#2. Java代码实战)

[3. 优缺点分析](#3. 优缺点分析)

四、灵魂拷问:实际开发中到底用哪个?

[1. 简单工厂 vs 工厂方法:选择指南](#1. 简单工厂 vs 工厂方法:选择指南)

[2. 现代 Java 开发的"第三条路":Spring 依赖注入 (DI)](#2. 现代 Java 开发的“第三条路”:Spring 依赖注入 (DI))

五、避坑指南与最佳实践

六、总结


摘要 :工厂模式是Java开发中最经典、使用频率最高的创建型设计模式之一。很多初学者容易陷入"为了模式而模式"的误区,导致代码过度设计。本文将通过清晰的Java代码示例,深入浅出地讲解简单工厂工厂方法 的核心区别,并结合Spring生态下的最佳实践,告诉你到底该在什么场景下用哪种工厂,助你写出既优雅又实用的代码。

一、为什么我们需要工厂模式?

在传统的面向对象编程中,我们习惯直接使用 new 关键字来创建对象:

java 复制代码
// 传统方式
Car myCar = new BenzCar();
myCar.drive();

这种方式虽然简单直接,但随着系统复杂度的提升,弊端逐渐显现:

  1. 耦合度高 :调用者依赖具体类(BenzCar),一旦类名变更或构造逻辑变化,所有 new 的地方都要修改。
  2. 违反开闭原则 :如果要增加新产品(如 TeslaCar),必须修改原有业务逻辑。
  3. 创建逻辑分散:如果对象创建需要复杂的校验、配置或日志记录,这些逻辑会散落在各个业务代码中,难以维护。

工厂模式的核心思想 就是:将对象的创建逻辑封装起来,让调用者只关心"用什么",而不关心"怎么造"

这就好比去餐厅点餐,你只需要告诉服务员"我要一份牛排",至于牛排是哪个厨师做的、怎么切的、怎么煎的,你不需要知道,服务员(工厂)会直接把做好的牛排(对象)端给你。


二、核心套路一:简单工厂 (Simple Factory)

1. 定义与结构

简单工厂(也称为静态工厂方法)是最基础的工厂模式。它创建一个专门的工厂类,根据传入的参数(如字符串、枚举)决定创建哪一种产品类的实例(看一遍就懂,很好理解)。

2. Java代码实战

假设我们要开发一个图形绘制模块,支持圆形和方形。

java 复制代码
// 1. 定义产品接口
interface Shape {
    void draw();
}

// 2. 具体产品实现
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("画了一个圆形 ⭕");
    }
}

class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("画了一个方形 ⬜");
    }
}

// 3. 简单工厂类
class ShapeFactory {
    // 使用静态方法,无需实例化工厂即可调用
    public static Shape createShape(String type) {
        if ("circle".equalsIgnoreCase(type)) {
            return new Circle();
        } else if ("square".equalsIgnoreCase(type)) {
            return new Square();
        } else {
            throw new IllegalArgumentException("未知的形状类型: " + type);
        }
    }
}

// 4. 客户端调用
public class SimpleFactoryDemo {
    public static void main(String[] args) {
        // 客户端只依赖接口 Shape 和工厂类,不依赖具体实现类
        Shape s1 = ShapeFactory.createShape("circle");
        s1.draw(); 

        Shape s2 = ShapeFactory.createShape("square");
        s2.draw(); 
    }
}

3. 优缺点分析

  • 优点
    • 结构简单,易于理解。
    • 客户端免除了直接创建产品的责任,实现了责任分离。
  • 缺点
    • 违反开闭原则 :如果要增加一个 Triangle(三角形),必须修改 ShapeFactory 中的 if-else 逻辑。在大型系统中,这可能导致工厂类变得臃肿且难以维护。

三、核心套路二:工厂方法 (Factory Method)

1. 定义与结构

工厂方法模式定义了一个创建对象的接口(抽象工厂),但让实现这个接口的子类来决定实例化哪一个类。工厂方法让类的实例化推迟到子类。

2. Java代码实战

假设我们要构建一个物流系统,支持陆运(卡车)和海运(轮船),且未来可能扩展空运。

java 复制代码
// 1. 定义产品接口
interface Transport {
    void deliver();
}

// 2. 具体产品实现
class Truck implements Transport {
    @Override
    public void deliver() {
        System.out.println("🚛 卡车通过公路运输货物");
    }
}

class Ship implements Transport {
    @Override
    public void deliver() {
        System.out.println("🚢 轮船通过海运运输货物");
    }
}

// 3. 抽象工厂 (Creator)
// 这里定义了业务逻辑框架,但把具体的创建过程留给子类
abstract class Logistics {
    // 工厂方法:由子类实现
    public abstract Transport createTransport();

    // 模板方法:包含通用业务逻辑
    public void planDelivery() {
        Transport transport = createTransport(); // 调用工厂方法
        System.out.print("物流计划启动:");
        transport.deliver();
    }
}

// 4. 具体工厂实现
class RoadLogistics extends Logistics {
    @Override
    public Transport createTransport() {
        return new Truck();
    }
}

class SeaLogistics extends Logistics {
    @Override
    public Transport createTransport() {
        return new Ship();
    }
}

// 5. 客户端调用
public class FactoryMethodDemo {
    public static void main(String[] args) {
        // 多态:父类引用指向子类对象
        Logistics roadLogistics = new RoadLogistics();
        roadLogistics.planDelivery(); 

        Logistics seaLogistics = new SeaLogistics();
        seaLogistics.planDelivery();
        
        // 【扩展性体现】:如果需要空运,只需新增 AirLogistics 和 Airplane 类,
        // 现有的 Logistics, RoadLogistics, SeaLogistics 代码一行都不用改!
    }
}

3. 优缺点分析

  • 优点
    • 符合开闭原则:增加新产品时,只需新增对应的具体工厂和产品类,无需修改现有代码。
    • 解耦彻底:高层模块只依赖抽象工厂和抽象产品。
  • 缺点
    • 类个数膨胀:每增加一个产品,就需要增加一个产品类和一个工厂类,系统复杂度增加。
    • 抽象性增加:增加了系统的理解难度。

四、灵魂拷问:实际开发中到底用哪个?

这是很多开发者最纠结的问题。答案并非非黑即白,而是取决于场景。

1. 简单工厂 vs 工厂方法:选择指南

维度 简单工厂 (Simple Factory) 工厂方法 (Factory Method)
使用频率 ⭐⭐⭐⭐ (高频) ⭐⭐ (中低频,多用于框架底层)
代码复杂度 高 (类数量多)
扩展性 一般 (需修改代码) 极好 (无需修改代码)
适用场景 工具类、策略选择、小型模块、产品类型固定 框架设计、插件系统、SDK、产品类型频繁变动

结论

  • 日常业务开发 :90% 的场景下,简单工厂(或其变种"静态工厂方法")完全够用。因为业务类型通常相对固定,为了扩展性牺牲代码简洁度是不划算的。
  • 框架/库开发 :如果你是在写一个供他人扩展的框架(如 JDBC 驱动、日志框架),工厂方法是标准答案,因为它能完美支持第三方插件的无缝接入。

2. 现代 Java 开发的"第三条路":Spring 依赖注入 (DI)

在 Spring Boot 统治的企业级开发中,我们其实很少手动写这两种工厂了

为什么?

因为 Spring 容器 已经帮你实现了终极版的"抽象工厂 + 简单工厂"。

  • 以前(手动工厂)

    java 复制代码
    // 痛苦地写 if-else 或者继承
    Service s = Factory.getService("mysql"); 
  • 现在(Spring DI)

    java 复制代码
    @Autowired
    private PaymentService paymentService; // Spring 自动帮你 new 好了
    
    // 或者通过构造函数注入
    public OrderController(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

在 Spring 中,你只需要定义接口和实现类,加上 @Component@Bean 注解,剩下的"工厂逻辑"全由框架处理。Spring 的 BeanFactory 本质上就是一个超级强大的简单工厂,配合配置文件或注解,实现了比传统工厂方法更灵活的扩展性。


五、避坑指南与最佳实践

  1. 拒绝过度设计

    如果你的系统只有 3 种类型,且一年都不会变,强行套用"工厂方法"搞出 6 个类,那是过度设计 ,会被同事吐槽的。简单工厂 + 静态方法往往更香。

  2. 善用静态工厂方法

    《Effective Java》强烈推荐用静态工厂方法代替构造器。例如:

    java 复制代码
    // 推荐写法
    LocalDate date = LocalDate.now(); 
    Optional<String> opt = Optional.of("value");
    // 而不是 new LocalDate() 或 new Optional()

    这其实就是简单工厂的最佳实践。

  3. 结合策略模式

    在实际业务中,工厂模式常与策略模式 搭配使用。例如文件上传场景,通过工厂根据配置(OSS、S3、本地)返回不同的上传策略对象,再结合 Spring 的 List<Service> 自动注入,可以实现零 if-else 的优雅代码。


六、总结

工厂模式是面向对象设计的基石之一。

  • 思想上 :推崇工厂方法,理解其"开闭原则"和"依赖倒置"的精髓,这是面试和架构设计的加分项。
  • 行动上 :日常开发首选 Spring 依赖注入 ,其次是 简单工厂(静态方法)
  • 口诀"能注入就注入,不能注入写个静态方法,除非你在写框架。"

希望这篇文章能帮你理清工厂模式的脉络,在实际项目中做出最合适的技术选型。

相关推荐
逆境不可逃1 个月前
【从零入门23种设计模式01】创建型之工厂模式(简单工厂+工厂方法+抽象工厂)
java·spring·设计模式·简单工厂模式·工厂方法模式·抽象工厂模式·工厂模式
sg_knight2 个月前
工厂方法模式(Factory Method)
java·服务器·python·设计模式·工厂方法模式·工厂模式
点云SLAM2 个月前
C++ 设计模式之工厂模式(Factory)和面试问题
开发语言·c++·设计模式·面试·c++11·工厂模式
callJJ2 个月前
Spring设计模式与依赖注入详解
java·spring·设计模式·idea·工厂模式
茶本无香2 个月前
设计模式之三—工厂模式:灵活对象创建的艺术
java·开发语言·设计模式·工厂模式
ttod_qzstudio2 个月前
从 Switch-Case 到自注册工厂:优雅的驱动行为管理系统重构
重构·typescript·工厂模式
西幻凌云3 个月前
认识设计模式——工厂模式
c++·设计模式·简单工厂模式·抽象工厂模式·工厂模式
老鼠只爱大米3 个月前
Java设计模式之代理模式(Proxy)深度解析
java·设计模式·代理模式·proxy pattern·java设计模式·proxypattern