什么是工厂模式?
工厂模式(Factory Pattern)是Java中最常用的创建型设计模式之一。它的核心思想是:将对象的创建与使用分离,调用者不需要知道对象的具体创建过程,只需要向工厂"订购"即可。
生活比喻
你去餐厅吃饭,不需要知道厨师是谁、厨房怎么运作、你只需要告诉服务员"我要一份宫保鸡丁",服务员就会让厨房去做。工厂模式就像这个服务员——它封装了对象创建的复杂过程,调用者只需要"点单"即可。
没有工厂模式 vs 有工厂模式:
❌ 没有工厂模式:
调用者 ──── new ProductA() ────> 需要知道所有产品类的存在
调用者 ──── new ProductB() ────> 类名硬编码,改动影响大
✓ 有工厂模式:
调用者 ──── Factory.create("A") ────> 不知道具体是哪个类
工厂 ──────────────────────────────────> 负责创建对象
为什么需要工厂模式?
解耦
调用者与产品类解耦,不需要import具体产品类
易于扩展
新增产品只需修改工厂,不影响调用者
隐藏细节
复杂创建过程封装在工厂内部
三种工厂模式
1. 简单工厂(Simple Factory)- 推荐指数:★★★☆☆
用一个工厂类根据参数创建不同的产品对象。这是最简单的形式,但不符合开闭原则(新增产品需要修改工厂)。
// 产品接口
interface Product {
void use();
}
// 具体产品A
class ProductA implements Product {
@Override
public void use() {
System.out.println("使用产品A");
}
}
// 具体产品B
class ProductB implements Product {
@Override
public void use() {
System.out.println("使用产品B");
}
}
// 简单工厂
class SimpleFactory {
public static Product create(String type) {
return switch (type) {
case "A" -> new ProductA();
case "B" -> new ProductB();
default -> throw new IllegalArgumentException("未知产品类型: " + type);
};
}
}
// 使用
public class SimpleFactoryDemo {
public static void main(String[] args) {
Product productA = SimpleFactory.create("A");
Product productB = SimpleFactory.create("B");
productA.use(); // 输出: 使用产品A
productB.use(); // 输出: 使用产品B
}
}
2. 工厂方法(Factory Method)- 推荐指数:★★★★☆
定义一个创建产品的接口,让子类决定实例化哪个类。符合开闭原则。
// 产品接口
interface Product {
void use();
}
// 产品A
class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("使用产品A");
}
}
// 产品B
class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("使用产品B");
}
}
// 工厂接口
interface Factory {
Product create();
}
// 对应产品的工厂
class FactoryA implements Factory {
@Override
public Product create() {
return new ConcreteProductA();
}
}
class FactoryB implements Factory {
@Override
public Product create() {
return new ConcreteProductB();
}
}
// 使用
public class FactoryMethodDemo {
public static void main(String[] args) {
Factory factoryA = new FactoryA();
Factory factoryB = new FactoryB();
Product productA = factoryA.create();
Product productB = factoryB.create();
productA.use();
productB.use();
}
}
3. 抽象工厂(Abstract Factory)- 推荐指数:★★★★☆
创建产品族(一系列相关的产品)的工厂。当产品有多个维度/系列时使用。
// 抽象产品 - 按钮
interface Button {
void render();
}
// 抽象产品 - 输入框
interface Input {
void render();
}
// ===== 现代风格产品族 =====
class ModernButton implements Button {
@Override
public void render() {
System.out.println("渲染现代风格按钮");
}
}
class ModernInput implements Input {
@Override
public void render() {
System.out.println("渲染现代风格输入框");
}
}
// ===== 古典风格产品族 =====
class ClassicButton implements Button {
@Override
public void render() {
System.out.println("渲染古典风格按钮");
}
}
class ClassicInput implements Input {
@Override
public void render() {
System.out.println("渲染古典风格输入框");
}
}
// 抽象工厂接口
interface UIFactory {
Button createButton();
Input createInput();
}
// 具体工厂 - 现代风格
class ModernUIFactory implements UIFactory {
@Override
public Button createButton() {
return new ModernButton();
}
@Override
public Input createInput() {
return new ModernInput();
}
}
// 具体工厂 - 古典风格
class ClassicUIFactory implements UIFactory {
@Override
public Button createButton() {
return new ClassicButton();
}
@Override
public Input createInput() {
return new ClassicInput();
}
}
// 使用
public class AbstractFactoryDemo {
public static void main(String[] args) {
// 使用现代风格
UIFactory modernFactory = new ModernUIFactory();
modernFactory.createButton().render();
modernFactory.createInput().render();
// 使用古典风格
UIFactory classicFactory = new ClassicUIFactory();
classicFactory.createButton().render();
classicFactory.createInput().render();
}
}
三种工厂模式对比
| 模式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 简单工厂 | 产品种类少、变化不频繁 | 简单直接 | 不符合开闭原则 |
| 工厂方法 | 一种产品(可扩展) | 符合开闭原则 | 类数量增加 |
| 抽象工厂 | 多个产品族/系列 | 产品一致性 | 扩展困难 |
工厂方法的应用场景
1
日志框架
根据配置创建不同的Logger(Log4j、Logback、SLF4J)
2
数据库驱动
JDBC通过DriverManager根据URL创建不同的Connection
3
UI组件库
创建不同主题(现代、古典)的UI组件
4
文档解析器
根据文件类型创建不同的解析器(PDF、Word、Excel)
小结
- 工厂模式将对象的创建与使用分离,降低耦合度
- 简单工厂:一个工厂创建多种产品,简单但不灵活
- 工厂方法:每种产品有对应工厂,符合开闭原则
- 抽象工厂:创建产品族,确保产品一致性
- 选择哪种工厂取决于产品复杂度和扩展需求