Java工厂模式案例如何实现:从基础到高级的完整指南
📖 目录导读
- 工厂模式概述 – 什么是工厂模式?为什么需要它?
- 简单工厂模式实现案例 – 最基础的工厂模式Java代码
- 工厂方法模式实现案例 – 遵循开闭原则的扩展方案
- 抽象工厂模式实现案例 – 应对产品族变化的终极方案
- 常见问题与问答 – 工厂模式在实际开发中的典型疑问
- 工厂模式在Spring框架中的应用 – 真实项目中的最佳实践
- 总结与选择建议 – 不同场景下如何选择工厂模式变体
工厂模式概述
工厂模式(Factory Pattern)是Java中最常用的创建型设计模式之一,它的核心思想是:将对象的创建过程封装起来,客户端不直接使用new关键字创建对象,而是通过一个工厂类来获取实例。

为什么需要工厂模式?
- 解耦:客户端代码与具体产品类解耦,只依赖抽象接口
- 复用:创建对象的逻辑集中管理,便于维护
- 扩展性:新增产品时,只需扩展工厂,无需修改客户端
简单工厂模式实现案例
场景:一个披萨店需要根据订单类型制作不同口味的披萨(芝士披萨、蔬菜披萨、海鲜披萨)。
// 产品接口
interface Pizza {
void prepare();
void bake();
void cut();
}
// 具体产品类
class CheesePizza implements Pizza {
public void prepare() { System.out.println("准备芝士披萨"); }
public void bake() { System.out.println("烘烤芝士披萨"); }
public void cut() { System.out.println("切芝士披萨"); }
}
class VeggiePizza implements Pizza {
public void prepare() { System.out.println("准备蔬菜披萨"); }
public void bake() { System.out.println("烘烤蔬菜披萨"); }
public void cut() { System.out.println("切蔬菜披萨"); }
}
// 简单工厂
class SimplePizzaFactory {
public static Pizza createPizza(String type) {
Pizza pizza = null;
if ("cheese".equals(type)) {
pizza = new CheesePizza();
} else if ("veggie".equals(type)) {
pizza = new VeggiePizza();
}
return pizza;
}
}
// 客户端使用
public class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = SimplePizzaFactory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
return pizza;
}
}
优点:代码简单,适合产品种类较少的场景。
缺点:新增产品需要修改工厂类的if-else,违反开闭原则。
工厂方法模式实现案例
场景:同一个披萨店扩展到纽约和芝加哥两个分店,每个分店对同种披萨的烹饪方式不同。
// 抽象创建者
abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
return pizza;
}
// 工厂方法,由子类实现
protected abstract Pizza createPizza(String type);
}
// 纽约分店
class NYPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
Pizza pizza = null;
if ("cheese".equals(type)) {
pizza = new NYCheesePizza(); // 纽约风格的芝士披萨
} else if ("veggie".equals(type)) {
pizza = new NYVeggiePizza();
}
return pizza;
}
}
// 芝加哥分店
class ChicagoPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
Pizza pizza = null;
if ("cheese".equals(type)) {
pizza = new ChicagoCheesePizza(); // 芝加哥深盘芝士披萨
}
return pizza;
}
}
核心变化:每个子类决定具体实例化哪个产品,客户端只需调用orderPizza。
优点:符合开闭原则,新增分店只需扩展子类。
缺点:每个产品类型需要对应一个具体工厂类,类数量增多。
抽象工厂模式实现案例
场景:披萨店现在需要提供组合套餐——不同地域的披萨+不同地域的饮料。
// 抽象产品族
interface Dough { String getDescription(); }
interface Sauce { String getDescription(); }
// 具体产品
class ThinCrustDough implements Dough {
public String getDescription() { return "薄脆面团"; }
}
class MarinaraSauce implements Sauce {
public String getDescription() { return "番茄酱"; }
}
// 抽象工厂
interface PizzaIngredientFactory {
Dough createDough();
Sauce createSauce();
}
// 具体工厂
class NYIngredientFactory implements PizzaIngredientFactory {
public Dough createDough() { return new ThinCrustDough(); }
public Sauce createSauce() { return new MarinaraSauce(); }
}
// 使用抽象工厂的Pizza类
class AbstractPizza {
Dough dough;
Sauce sauce;
void prepare(PizzaIngredientFactory factory) {
dough = factory.createDough();
sauce = factory.createSauce();
System.out.println("准备" + dough.getDescription() + "和" + sauce.getDescription());
}
}
结构说明:
- 抽象工厂:声明创建不同产品族的方法
- 具体工厂:实现产品族的创建
- 抽象产品:每个产品族有各自的接口
- 具体产品:不同工厂生产不同风格的产品
优点:保证同一产品族的产品一起使用,新增产品族不影响现有代码。
缺点:扩展新类型产品困难(需修改抽象工厂接口)。
常见问题与问答
❓ 问:简单工厂算不算真正的设计模式?
答:简单工厂不是GoF23种设计模式之一,它更像一种编程习惯或编程技巧,但它作为学习工厂模式的入门,非常直观易懂。
❓ 问:工厂模式与策略模式有什么区别?
答:
- 核心目的不同:工厂模式是创建型,关注对象如何被实例化;策略模式是行为型,关注算法如何被封装和替换。
- 使用场景不同:工厂模式解决“应该创建哪个对象”;策略模式解决“应该执行哪个算法”。
❓ 问:工厂方法模式和抽象工厂模式如何选择?
答:
- 工厂方法:当你的系统只需要一个产品等级结构(例如只有Pizza这个产品类别,但地域风味不同)时使用。
- 抽象工厂:当你的系统需要多个产品等级结构(例如Pizza + 饮料 + 甜点,不同地域有不同的组合套餐)时使用。
❓ 问:实际项目中Spring Bean工厂是哪种模式?
答:Spring的BeanFactory和ApplicationContext本质上是工厂模式+单例模式的复合体,它通过配置元数据(XML、注解)动态创建和管理Bean对象,兼具了简单工厂的灵活性(通过字符串ID获取Bean)和工厂方法的扩展性(支持自定义Bean创建逻辑)。
工厂模式在Spring框架中的应用
Spring IOC容器是工厂模式最经典的实际应用:
// Spring通过ApplicationContext获取实例
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = context.getBean("userService", UserService.class);
实现原理:
BeanFactory接口定义了获取Bean的工厂方法getBean()DefaultListableBeanFactory是核心实现类,维护了Bean定义映射表- 通过反射机制动态调用构造器或工厂方法创建Bean实例
优势:用户无需手动new对象,所有依赖由容器注入,极大降低了模块间耦合度。
总结与选择建议
| 模式类型 | 核心特征 | 适用场景 | 类复杂度 |
|---|---|---|---|
| 简单工厂 | 集中管理创建逻辑 | 产品种类少、变化不频繁 | 低 |
| 工厂方法 | 子类决定具体产品 | 产品种类多、需要地域化定制 | 中 |
| 抽象工厂 | 创建产品族 | 需要成套产品、产品族风格统一 | 高 |
实际开发中的最佳实践:
- 项目初期可以使用简单工厂快速迭代
- 当发现频繁新增产品时,重构为工厂方法模式
- 如果业务涉及多个产品维度(如不同品牌的不同系列),果断采用抽象工厂模式
通过本文的案例解析,你应该已经掌握了工厂模式在Java中的完整实现方法。设计模式是用在合适场景的解决方案,而不是强行套用的模板,在面对具体的业务需求时,选择最简单的能解决问题的模式,往往比堆砌复杂模式更有效。