工厂模式在Java中的深度解析:从入门到实战应用
📚 目录导读
- 什么是工厂模式? —— 核心概念与设计初衷
- 工厂模式的三大变体 —— 简单工厂、工厂方法、抽象工厂
- Java代码实战 —— 完整案例演示(含问答)
- 工厂模式在主流框架中的应用 —— Spring、MyBatis中的影子
- 常见误区与最佳实践 —— 你真的用对了吗?
- 工厂模式 vs 其他创建型模式 —— 何时选择工厂?
- 高频面试问答 —— 帮你通过大厂面试
什么是工厂模式?核心概念与设计初衷
工厂模式(Factory Pattern)是Java中最常用的创建型设计模式之一,其核心思想是:将对象的创建与使用分离,当客户端需要创建一个对象时,不再直接使用new关键字,而是通过一个“工厂”类来负责实例化逻辑。

为什么需要工厂模式?
- 解耦:调用方无需知道具体类的构造细节,只需知道工厂接口。
- 扩展性:增加新类时,只需扩展工厂逻辑,无需修改客户端代码(符合开闭原则)。
- 统一管理:可以将复杂的对象创建逻辑(如依赖注入、参数校验)集中到工厂中。
权威参考: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的BeanFactory和ApplicationContext本身就是抽象工厂的经典实现:
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:核心的BeanFactory、FactoryBean接口(允许自定义复杂Bean创建逻辑)、@Component注解下的自动装配(背后也是IoC容器的工厂机制)。
工厂模式是Java开发者必须熟练掌握的设计模式,它不仅是代码解耦的利器,也是理解Spring等主流框架内部机制的基础,从简单的简单工厂到灵活的抽象工厂,选择取决于你的扩展需求:如果只是一两个产品变体,工厂方法足够;如果涉及产品族(如多系统适配),抽象工厂才是正解。
行动建议:拿出你最近的一个项目,看看有没有用new创建对象且后续可能需要扩展的地方,尝试用工厂模式重构,你会立刻感受到代码维护性的提升。
参考来源:GoF《设计模式》、Spring官方文档、StackOverflow常见问答。