抽象工厂模式 (Abstract Factory) 全面讲解
学习笔记
设计模式
抽象工厂模式
Java
面向对象
软件设计
编程模式
本文全面讲解了抽象工厂模式,包括其定义、核心思想、与工厂方法模式的区别、应用场景、结构以及具体实现。
date: 2025-06-22T19:31:00 tags:
- 复习
- Java
- 面向对象
抽象工厂模式 (Abstract Factory) 全面讲解
1. 什么是抽象工厂模式?
抽象工厂模式是创建型设计模式,用于生产一系列相关或依赖的对象,而无需指定它们的具体类。
- 核心思想:提供一个接口,用于创建多个产品族(如不同风格的UI组件:Windows/Mac按钮、文本框等)。
- 类比:家具工厂生产整套家具(椅子+桌子+沙发),而不是单一产品。
🔹 和工厂方法模式的区别
| 模式 | 工厂方法 (Factory Method) | 抽象工厂 (Abstract Factory) |
|---|---|---|
| 目标 | 创建单一产品(如Car) | 创建多个相关产品(如Car + Engine + Wheel) |
| 层级 | 一个方法对应一个产品 | 一个工厂对应一个产品族 |
2. 为什么需要抽象工厂模式?
问题场景
假设需要开发一个跨平台UI库,支持Windows和Mac两种风格的按钮和文本框:
// 直接硬编码的问题:
Button winButton = new WinButton();
TextBox macTextBox = new MacTextBox();
// 问题:代码耦合,切换平台需要大量修改!
解决方案
用抽象工厂封装同一风格的所有组件创建,客户端只需切换工厂即可换整套风格。
3. 抽象工厂模式的结构
角色说明
AbstractFactory(抽象工厂)- 声明创建一组产品的接口(如
createButton(),createTextBox())。
- 声明创建一组产品的接口(如
ConcreteFactory(具体工厂)- 实现抽象工厂,生产同一产品族的对象(如
WinFactory生产Windows风格组件)。
- 实现抽象工厂,生产同一产品族的对象(如
AbstractProduct(抽象产品)- 定义产品的接口(如
Button、TextBox)。
- 定义产品的接口(如
ConcreteProduct(具体产品)- 实现抽象产品(如
WinButton、MacTextBox)。
- 实现抽象产品(如
4. 示例代码(跨平台UI组件)
步骤1:定义抽象产品
// 抽象产品:按钮
public interface Button {
void render();
}
// 抽象产品:文本框
public interface TextBox {
void show();
}
步骤2:定义具体产品
// Windows风格组件
public class WinButton implements Button {
@Override
public void render() {
System.out.println("Windows按钮");
}
}
public class WinTextBox implements TextBox {
@Override
public void show() {
System.out.println("Windows文本框");
}
}
// Mac风格组件
public class MacButton implements Button {
@Override
public void render() {
System.out.println("Mac按钮");
}
}
public class MacTextBox implements TextBox {
@Override
public void show() {
System.out.println("Mac文本框");
}
}
步骤3:定义抽象工厂
public interface GUIFactory {
Button createButton();
TextBox createTextBox();
}
步骤4:定义具体工厂
// Windows工厂
public class WinFactory implements GUIFactory {
@Override
public Button createButton() {
return new WinButton();
}
@Override
public TextBox createTextBox() {
return new WinTextBox();
}
}
// Mac工厂
public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public TextBox createTextBox() {
return new MacTextBox();
}
}
步骤5:客户端调用
public class Client {
public static void main(String[] args) {
// 只需切换工厂即可换整套UI风格
GUIFactory factory = new MacFactory(); // 改为WinFactory即切换为Windows风格
Button button = factory.createButton();
TextBox textBox = factory.createTextBox();
button.render(); // 输出:Mac按钮
textBox.show(); // 输出:Mac文本框
}
}
5. 关键点总结
- 适用场景:
- 系统需要独立于产品的创建、组合和表示(如跨平台UI、游戏不同主题的地图/NPC)。
- 强调一系列相关产品的一致性(如不能混用Windows按钮和Mac文本框)。
- 优点:
- 客户端代码与具体类解耦。
- 易于扩展新产品族(新增一个工厂即可)。
- 缺点:
- 新增产品类型(如新增
Checkbox)需要修改所有工厂接口。
- 新增产品类型(如新增
6. 互动实践
问题1:以下代码是抽象工厂吗?为什么?
public class SimpleFactory {
public Button createButton(String type) {
if ("Win".equals(type)) return new WinButton();
else if ("Mac".equals(type)) return new MacButton();
return null;
}
}
答案:不是!这是简单工厂,抽象工厂需要生产多个相关产品(如按钮+文本框)。
问题2:如何扩展支持Linux风格的UI?
任务:
- 新增
LinuxButton和LinuxTextBox类。 - 新增
LinuxFactory实现GUIFactory接口。
7. 考试练习题
题目1(概念题)
抽象工厂模式的主要作用是?
A. 创建单个对象
B. 创建一组相关对象
C. 替代继承
D. 优化算法性能
答案:B
题目2(代码填空)
补全抽象工厂模式的代码:
public interface FurnitureFactory {
Chair createChair();
Table ____(); // 填空1
}
public class ModernChair implements Chair { /*...*/ }
public class ModernTable implements Table { /*...*/ }
public class ModernFactory implements FurnitureFactory {
@Override
public Chair createChair() {
return ____; // 填空2
}
@Override
public Table ____() { // 填空3
return new ModernTable();
}
}
答案:
createTablenew ModernChair()createTable
题目3(设计题)
用抽象工厂模式设计一个游戏角色系统,包含:
- 产品族:
Warrior(战士)、Mage(法师) - 风格:
Fantasy(奇幻风格)、SciFi(科幻风格)
要求:画出类图并写出关键代码。
答案:
- 抽象产品:
Warrior、Mage接口。 - 具体产品:
FantasyWarrior、SciFiMage等。 - 抽象工厂:
CharacterFactory(含createWarrior()和createMage())。 - 具体工厂:
FantasyFactory、SciFiFactory。