问题
抽象工厂模式与工厂方法模式有何区别?
答案
一、核心概念
工厂方法模式(Factory Method):定义一个创建对象的接口,让子类决定实例化哪个类。工厂方法将对象的实例化延迟到子类。
抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
二、关键区别
| 维度 | 工厂方法模式 | 抽象工厂模式 |
|---|---|---|
| 产品层级 | 针对单一产品等级结构 | 针对多个产品等级结构 |
| 抽象程度 | 一个抽象产品类 | 多个抽象产品类 |
| 工厂职责 | 创建一种产品 | 创建一系列相关产品 |
| 扩展方式 | 增加新产品需要新增工厂子类 | 增加新产品族需要修改所有工厂 |
| 使用场景 | 产品种类单一但实现多样 | 产品成套出现,需要保证兼容性 |
三、工厂方法模式示例
// 抽象产品
interface Product {
void use();
}
// 具体产品
class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("使用产品A");
}
}
class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("使用产品B");
}
}
// 抽象工厂
abstract class Factory {
public abstract Product createProduct();
}
// 具体工厂
class FactoryA extends Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
class FactoryB extends Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
// 使用
Factory factory = new FactoryA();
Product product = factory.createProduct();
product.use();
四、抽象工厂模式示例
// 抽象产品族:按钮和文本框
interface Button {
void display();
}
interface TextField {
void render();
}
// Windows 风格产品
class WindowsButton implements Button {
@Override
public void display() {
System.out.println("显示 Windows 风格按钮");
}
}
class WindowsTextField implements TextField {
@Override
public void render() {
System.out.println("渲染 Windows 风格文本框");
}
}
// Mac 风格产品
class MacButton implements Button {
@Override
public void display() {
System.out.println("显示 Mac 风格按钮");
}
}
class MacTextField implements TextField {
@Override
public void render() {
System.out.println("渲染 Mac 风格文本框");
}
}
// 抽象工厂
interface GUIFactory {
Button createButton();
TextField createTextField();
}
// 具体工厂
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextField createTextField() {
return new WindowsTextField();
}
}
class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public TextField createTextField() {
return new MacTextField();
}
}
// 使用
GUIFactory factory = new WindowsFactory();
Button button = factory.createButton();
TextField textField = factory.createTextField();
button.display();
textField.render();
五、实际应用场景
工厂方法模式:
- JDBC 中的
Connection创建(不同数据库驱动提供不同实现) - Spring 的
FactoryBean接口 - 日志框架中不同级别日志对象的创建
抽象工厂模式:
- 跨平台 UI 组件库(Windows/Mac/Linux 风格)
- 数据库访问层(MySQL/Oracle/PostgreSQL 的 Connection、Statement、ResultSet)
- 游戏开发中的场景工厂(不同关卡的敌人、道具、地图组合)
六、选择建议
使用工厂方法模式:
- 只需要创建一种类型的产品
- 产品的创建逻辑较为复杂,需要封装
- 需要灵活扩展产品种类
使用抽象工厂模式:
- 需要创建一系列相关的产品对象
- 产品之间存在约束关系(如 UI 风格统一)
- 系统需要在多个产品族中切换
七、面试答题要点
- 核心区别:工厂方法针对单一产品,抽象工厂针对产品族
- 结构差异:工厂方法一个工厂方法创建一个产品;抽象工厂多个工厂方法创建多个相关产品
- 扩展性:工厂方法符合开闭原则,易于扩展新产品;抽象工厂增加新产品需要修改接口
- 实际应用:能举出 Spring、JDBC 等框架中的实际例子