工厂模式在Java中怎么用?

wen python案例 2

工厂模式在Java中的深度解析:从入门到实战应用

📚 目录导读

  1. 什么是工厂模式? —— 核心概念与设计初衷
  2. 工厂模式的三大变体 —— 简单工厂、工厂方法、抽象工厂
  3. Java代码实战 —— 完整案例演示(含问答)
  4. 工厂模式在主流框架中的应用 —— Spring、MyBatis中的影子
  5. 常见误区与最佳实践 —— 你真的用对了吗?
  6. 工厂模式 vs 其他创建型模式 —— 何时选择工厂?
  7. 高频面试问答 —— 帮你通过大厂面试

什么是工厂模式?核心概念与设计初衷

工厂模式(Factory Pattern)是Java中最常用的创建型设计模式之一,其核心思想是:将对象的创建与使用分离,当客户端需要创建一个对象时,不再直接使用new关键字,而是通过一个“工厂”类来负责实例化逻辑。

工厂模式在Java中怎么用?

为什么需要工厂模式?

  • 解耦:调用方无需知道具体类的构造细节,只需知道工厂接口。
  • 扩展性:增加新类时,只需扩展工厂逻辑,无需修改客户端代码(符合开闭原则)。
  • 统一管理:可以将复杂的对象创建逻辑(如依赖注入、参数校验)集中到工厂中。

权威参考:GoF《设计模式》明确指出,工厂模式适用于“当一个类无法预知它必须创建的对象的类”时。


工厂模式的三大变体

简单工厂(Simple Factory)

严格来说不属于23种设计模式,但最实用,通过一个静态方法接收参数,返回不同子类实例。

代码示意

public class SimpleFactory {
    public static Product createProduct(String type) {
        if ("A".equals(type)) return new ProductA();
        else if ("B".equals(type)) return new ProductB();
        return null;
    }
}

工厂方法(Factory Method)

定义一个创建对象的接口,让子类决定实例化哪个类,每个具体工厂对应一个产品。

结构

  • 抽象工厂(Factory)→ 声明工厂方法
  • 具体工厂(ConcreteFactory)→ 实现工厂方法,返回具体产品

抽象工厂(Abstract Factory)

提供创建一系列相关或相互依赖对象的接口,无需指定具体类,适合产品族管理。

典型应用:GUI库(如Windows按钮 vs Mac按钮的成套创建)


Java代码实战:一个完整的电商订单场景

场景:根据用户类型(普通用户、VIP用户、企业用户)创建不同的折扣策略对象。

步骤1:定义产品接口

public interface DiscountStrategy {
    double applyDiscount(double originalPrice);
}

步骤2:实现具体产品

public class NormalDiscount implements DiscountStrategy {
    public double applyDiscount(double price) { return price * 0.95; }
}
public class VipDiscount implements DiscountStrategy {
    public double applyDiscount(double price) { return price * 0.8; }
}
public class EnterpriseDiscount implements DiscountStrategy {
    public double applyDiscount(double price) { return price * 0.7; }
}

步骤3:实现工厂方法模式

// 抽象工厂
public interface DiscountFactory {
    DiscountStrategy createDiscount();
}
// 具体工厂
public class NormalDiscountFactory implements DiscountFactory {
    public DiscountStrategy createDiscount() { return new NormalDiscount(); }
}
public class VipDiscountFactory implements DiscountFactory {
    public DiscountStrategy createDiscount() { return new VipDiscount(); }
}

步骤4:客户端使用

public class OrderService {
    public double calculatePrice(DiscountFactory factory, double price) {
        DiscountStrategy strategy = factory.createDiscount();
        return strategy.applyDiscount(price);
    }
}
// 调用示例
new OrderService().calculatePrice(new VipDiscountFactory(), 100.0); // 输出80.0

❓ 问答环节

Q:为什么这里不用简单工厂而用工厂方法?
A:简单工厂违反了开闭原则——增加新产品时需修改已有工厂类;而工厂方法通过添加新工厂类实现扩展,客户端只依赖抽象工厂。


工厂模式在主流框架中的应用

Spring Framework

Spring的BeanFactoryApplicationContext本身就是抽象工厂的经典实现:

  • getBean("beanName") 通过工厂方法创建对象
  • 支持单例、原型等作用域

MyBatis

SqlSessionFactory是工厂角色的代表,它负责创建SqlSession实例,而具体的数据库操作封装在SqlSession中。

Java标准库

  • java.util.Calendar.getInstance() → 简单工厂
  • java.text.NumberFormat.getInstance() → 工厂方法

常见误区与最佳实践

❌ 误区1:滥用工厂模式

当创建对象逻辑极其简单(如只有一个无参构造)时,直接new反而更清晰。

❌ 误区2:工厂与单例不分

工厂模式负责创建,单例模式负责控制实例数,两者可以结合使用(如Spring的单例池)。

✅ 最佳实践

  • 多用工厂方法,少用简单工厂:保持扩展性
  • 配合依赖注入(DI):由Spring管理工厂,实现松耦合
  • 为复杂对象使用工厂:如对象需要读取配置、初始化状态

工厂模式 vs 其他创建型模式

模式 核心区别 使用场景
工厂模式 由子类决定实例化哪个类 需要扩展产品类时
建造者模式 逐步构建复杂对象,控制构建过程 对象参数过多或有构建顺序要求
原型模式 通过克隆现有对象创建新对象 对象创建成本高,且需要保持状态

选择口诀:对象简单用工厂,组合复杂用建造,性能要求用原型。


高频面试问答(必考)

Q1:简单工厂和工厂方法有什么区别?

A:简单工厂通过判断逻辑返回产品,属于“上帝类”,违反开闭原则;工厂方法通过多态让子类决定产品创建,符合开闭原则,实际项目中通常从简单工厂演进到工厂方法。

Q2:抽象工厂和工厂方法有什么区别?

A:工厂方法针对“一种产品”的创建,提供一种抽象方法;抽象工厂针对“一个产品族”的创建,提供一整系列方法的集合,汽车工厂(引擎+轮胎+座椅)需用抽象工厂。

Q3:工厂模式解决了什么问题?

A:解决了“new”带来的硬编码耦合问题,使得客户端不直接依赖具体类,而是依赖抽象接口,同时将创建逻辑集中,便于统一生命周期管理。

Q4:Spring中哪些地方使用了工厂模式?

A:核心的BeanFactoryFactoryBean接口(允许自定义复杂Bean创建逻辑)、@Component注解下的自动装配(背后也是IoC容器的工厂机制)。


工厂模式是Java开发者必须熟练掌握的设计模式,它不仅是代码解耦的利器,也是理解Spring等主流框架内部机制的基础,从简单的简单工厂到灵活的抽象工厂,选择取决于你的扩展需求:如果只是一两个产品变体,工厂方法足够;如果涉及产品族(如多系统适配),抽象工厂才是正解。

行动建议:拿出你最近的一个项目,看看有没有用new创建对象且后续可能需要扩展的地方,尝试用工厂模式重构,你会立刻感受到代码维护性的提升。

参考来源:GoF《设计模式》、Spring官方文档、StackOverflow常见问答。

抱歉,评论功能暂时关闭!