Abstract Factory 模式

  • ~6.00K 字
  1. 1. Abstract Factory 模式
    1. 1.1. 一、基础介绍
    2. 1.2. 二、生活比喻:家具工厂
    3. 1.3. 三、应用场景
    4. 1.4. 四、使用注意事项
      1. 1.4.1. 优点
      2. 1.4.2. 缺点
    5. 1.5. 五、Java 经典案例
      1. 1.5.1. GUI 组件工厂
    6. 1.6. 六、Python 经典案例
      1. 1.6.1. 主题工厂(暗色/亮色主题)
    7. 1.7. 七、参考资料与延伸阅读
      1. 1.7.1. 经典书籍
      2. 1.7.2. 在线资源
      3. 1.7.3. 相关设计模式
      4. 1.7.4. 最佳实践建议

Abstract Factory 模式

一、基础介绍

Abstract Factory(抽象工厂)模式是一种创建型设计模式,它提供一个接口,用于创建相关或依赖对象家族,而不需要明确指定具体类。

抽象工厂模式的核心思想是:将一组相关的对象(产品族)的创建封装在一起,客户端通过抽象接口操作,无需关心具体实现

二、生活比喻:家具工厂

想象一家跨国家具公司

传统方式:如果你想买一套北欧风格的沙发和茶几,需要去北欧风格的店;如果想要中式风格的,又要去中式风格的店。每次更换风格,都要找不同的供应商。

抽象工厂方式:家具公司提供统一的订购接口(AbstractFactory),你只需要告诉它”我要北欧风格”或”我要中式风格”,它就会为你搭配好整套家具(沙发+茶几+餐桌),保证风格统一。

在这个比喻中:

  • AbstractFactory = 家具订购接口
  • ConcreteFactory = 北欧风格工厂、中式风格工厂
  • AbstractProduct = 抽象家具(沙发、茶几、餐桌)
  • ConcreteProduct = 北欧沙发、中式茶几等具体产品

三、应用场景

场景 说明 示例
产品族创建 需要创建一系列相关对象 GUI组件族(按钮+窗口)
多系列切换 系统支持多种产品族 不同风格的UI主题
跨平台开发 不同平台需要不同实现 Windows/Mac/Linux组件
数据库兼容 支持多种数据库 MySQL/PostgreSQL/Oracle

四、使用注意事项

优点

优点 说明
产品族一致性 确保同一工厂的产品族配套使用
解耦创建与使用 客户端不依赖具体类
符合开闭原则 新增产品族无需修改现有代码
易于切换 可以轻松切换整个产品族

缺点

缺点 说明
扩展困难 新增产品种类需要修改所有工厂
复杂性增加 类层级结构复杂
抽象性强 代码更抽象,理解成本高
过度设计 简单场景可能过度设计

五、Java 经典案例

GUI 组件工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// 抽象产品
interface Button {
void render();
void onClick();
}

interface Checkbox {
void render();
void toggle();
}

// 具体产品 - Windows 风格
class WindowsButton implements Button {
public void render() {
System.out.println("Rendering Windows button");
}
public void onClick() {
System.out.println("Windows button clicked");
}
}

class WindowsCheckbox implements Checkbox {
public void render() {
System.out.println("Rendering Windows checkbox");
}
public void toggle() {
System.out.println("Windows checkbox toggled");
}
}

// 具体产品 - Mac 风格
class MacButton implements Button {
public void render() {
System.out.println("Rendering Mac button");
}
public void onClick() {
System.out.println("Mac button clicked");
}
}

class MacCheckbox implements Checkbox {
public void render() {
System.out.println("Rendering Mac checkbox");
}
public void toggle() {
System.out.println("Mac checkbox toggled");
}
}

// 抽象工厂
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}

// 具体工厂
class WindowsFactory implements GUIFactory {
public Button createButton() {
return new WindowsButton();
}
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}

class MacFactory implements GUIFactory {
public Button createButton() {
return new MacButton();
}
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}

// 客户端
class Application {
private Button button;
private Checkbox checkbox;

public Application(GUIFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}

public void render() {
button.render();
checkbox.render();
}
}

// 使用
public class AbstractFactoryDemo {
public static void main(String[] args) {
GUIFactory factory = System.getProperty("os.name").toLowerCase().contains("mac")
? new MacFactory()
: new WindowsFactory();

Application app = new Application(factory);
app.render();
}
}

六、Python 经典案例

主题工厂(暗色/亮色主题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from abc import ABC, abstractmethod
from typing import Protocol


class Button(Protocol):
def render(self) -> None: ...
def click(self) -> None: ...


class Checkbox(Protocol):
def render(self) -> None: ...
def toggle(self) -> None: ...


class ThemeFactory(ABC):
@abstractmethod
def create_button(self) -> Button: pass

@abstractmethod
def create_checkbox(self) -> Checkbox: pass


# 亮色主题产品族
class LightButton:
def render(self) -> None:
print("Rendering Light button")
def click(self) -> None:
print("Light button clicked")


class LightCheckbox:
def render(self) -> None:
print("Rendering Light checkbox")
def toggle(self) -> None:
print("Light checkbox toggled")


class LightThemeFactory(ThemeFactory):
def create_button(self) -> Button:
return LightButton()
def create_checkbox(self) -> Checkbox:
return LightCheckbox()


# 暗色主题产品族
class DarkButton:
def render(self) -> None:
print("Rendering Dark button")
def click(self) -> None:
print("Dark button clicked")


class DarkCheckbox:
def render(self) -> None:
print("Rendering Dark checkbox")
def toggle(self) -> None:
print("Dark checkbox toggled")


class DarkThemeFactory(ThemeFactory):
def create_button(self) -> Button:
return DarkButton()
def create_checkbox(self) -> Checkbox:
return DarkCheckbox()


# 客户端
class Application:
def __init__(self, factory: ThemeFactory):
self.button = factory.create_button()
self.checkbox = factory.create_checkbox()

def render(self):
self.button.render()
self.checkbox.render()


# 使用
def main():
factory = DarkThemeFactory() # 或 LightThemeFactory()
app = Application(factory)
app.render()


if __name__ == "__main__":
main()

七、参考资料与延伸阅读

经典书籍

  • 《设计模式:可复用面向对象软件的基础》- GoF
  • 《Head First 设计模式》- 抽象工厂模式章节

在线资源

相关设计模式

  • Factory Method:创建单个对象,Abstract Factory 创建产品族
  • Builder:关注构建复杂对象,Abstract Factory 关注产品族
  • Prototype:可以用原型存储产品族实例
  • Singleton:具体工厂通常是单例
  • Facade:可以用 Abstract Factory 简化子系统创建

最佳实践建议

  1. 产品族稳定时使用,频繁变动时不适用
  2. 一个工厂对应一个产品族
  3. 保持产品族的一致性
  4. 新增产品种类代价大,谨慎设计
打赏
打赏提示信息