工厂方法模式

工厂方法模式是GoF 23种经典创建型设计模式之一,核心价值在于解耦对象的创建与使用,通过抽象化设计满足“开闭原则”,让系统在不修改原有代码的前提下灵活扩展产品类型。本文将从模式核心结构入手,详解其工作原理,提供C#、Python、Golang、C++及纯C语言的落地实现,并分析优缺点与适用场景,帮助开发者快速掌握该模式的实际应用。

一、工厂方法模式的核心结构

工厂方法模式通过分层设计,将产品创建逻辑抽象化,核心包含4个角色,各角色职责清晰、分工明确,共同实现“创建与使用分离”的目标,具体结构如下:

1.1 核心角色定义

  • 抽象产品(Abstract Product):定义产品的统一规范,描述产品的核心行为与属性,是所有具体产品的父类(或接口)。例如“电子设备”抽象类,定义“开机”“关机”等通用方法。

  • 具体产品(Concrete Product):实现抽象产品的接口,是工厂方法模式的最终创建目标,与具体工厂一一对应。例如“手机”“电脑”,均继承自“电子设备”,并实现各自的开机、关机逻辑。

  • 抽象工厂(Abstract Factory):定义创建产品的抽象接口(仅声明创建方法,不实现具体逻辑),是所有具体工厂的父类(或接口),负责约束具体工厂的行为。

  • 具体工厂(Concrete Factory):继承或实现抽象工厂,重写创建产品的方法,负责具体产品的实例化,是连接抽象产品与具体产品的桥梁。

1.2 核心工作流程

  1. 客户端无需直接创建产品,仅需依赖抽象工厂;2. 客户端根据需求选择具体工厂;3. 具体工厂调用自身的创建方法,生成对应的具体产品;4. 客户端通过抽象产品接口使用产品,无需关注产品的具体实现细节。

这种流程设计的核心优势的是“扩展无侵入”——新增产品时,只需新增具体产品类和对应具体工厂类,无需修改抽象工厂、已有具体工厂及客户端代码,完美契合开闭原则。

二、多语言实现(统一场景:电子设备创建)

以下以“电子设备创建”为统一场景(抽象产品:电子设备;具体产品:手机、电脑;抽象工厂:电子设备工厂;具体工厂:手机工厂、电脑工厂),分别实现工厂方法模式,覆盖5种主流语言,兼顾语法特性与模式核心。

2.1 C# 实现(抽象类+继承)

C#作为强类型面向对象语言,通过抽象类+继承天然适配工厂方法模式,语法简洁且类型安全,适合企业级开发场景。

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
using System;

// 1. 抽象产品:电子设备
public abstract class ElectronicDevice
{
// 抽象方法:开机
public abstract void PowerOn();
// 抽象方法:关机
public abstract void PowerOff();
}

// 2. 具体产品1:手机
public class MobilePhone : ElectronicDevice
{
public override void PowerOn()
{
Console.WriteLine("手机开机,启动操作系统...");
}

public override void PowerOff()
{
Console.WriteLine("手机关机,保存数据...");
}
}

// 2. 具体产品2:电脑
public class Computer : ElectronicDevice
{
public override void PowerOn()
{
Console.WriteLine("电脑开机,加载驱动程序...");
}

public override void PowerOff()
{
Console.WriteLine("电脑关机,关闭后台进程...");
}
}

// 3. 抽象工厂:电子设备工厂
public abstract class ElectronicDeviceFactory
{
// 抽象创建方法
public abstract ElectronicDevice CreateDevice();
}

// 4. 具体工厂1:手机工厂
public class MobilePhoneFactory : ElectronicDeviceFactory
{
public override ElectronicDevice CreateDevice()
{
Console.WriteLine("手机工厂:创建手机实例");
return new MobilePhone();
}
}

// 4. 具体工厂2:电脑工厂
public class ComputerFactory : ElectronicDeviceFactory
{
public override ElectronicDevice CreateDevice()
{
Console.WriteLine("电脑工厂:创建电脑实例");
return new Computer();
}
}

// 客户端调用
class Client
{
static void Main(string[] args)
{
// 1. 创建手机工厂,获取手机产品
ElectronicDeviceFactory mobileFactory = new MobilePhoneFactory();
ElectronicDevice mobile = mobileFactory.CreateDevice();
mobile.PowerOn();
mobile.PowerOff();

// 2. 创建电脑工厂,获取电脑产品
ElectronicDeviceFactory computerFactory = new ComputerFactory();
ElectronicDevice computer = computerFactory.CreateDevice();
computer.PowerOn();
computer.PowerOff();
}
}

2.2 Python 实现(abc模块+动态特性)

Python无严格的抽象类语法,通过abc模块实现抽象接口,结合动态语言的灵活性,简化工厂与产品的定义,代码简洁易读。

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
from abc import ABC, abstractmethod

# 1. 抽象产品:电子设备
class ElectronicDevice(ABC):
@abstractmethod
def power_on(self):
"""抽象方法:开机"""
pass

@abstractmethod
def power_off(self):
"""抽象方法:关机"""
pass

# 2. 具体产品1:手机
class MobilePhone(ElectronicDevice):
def power_on(self):
print("手机开机,启动操作系统...")

def power_off(self):
print("手机关机,保存数据...")

# 2. 具体产品2:电脑
class Computer(ElectronicDevice):
def power_on(self):
print("电脑开机,加载驱动程序...")

def power_off(self):
print("电脑关机,关闭后台进程...")

# 3. 抽象工厂:电子设备工厂
class ElectronicDeviceFactory(ABC):
@abstractmethod
def create_device(self):
"""抽象创建方法"""
pass

# 4. 具体工厂1:手机工厂
class MobilePhoneFactory(ElectronicDeviceFactory):
def create_device(self):
print("手机工厂:创建手机实例")
return MobilePhone()

# 4. 具体工厂2:电脑工厂
class ComputerFactory(ElectronicDeviceFactory):
def create_device(self):
print("电脑工厂:创建电脑实例")
return Computer()

# 客户端调用
if __name__ == "__main__":
# 获取手机产品
mobile_factory = MobilePhoneFactory()
mobile = mobile_factory.create_device()
mobile.power_on()
mobile.power_off()

# 获取电脑产品
computer_factory = ComputerFactory()
computer = computer_factory.create_device()
computer.power_on()
computer.power_off()

2.3 Golang 实现(接口+结构体)

Golang无类继承特性,通过“接口+结构体”实现多态,核心是定义产品接口和工厂接口,结构体实现接口方法,贴合Go语言“面向接口编程”的设计理念。

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
package main

import "fmt"

// 1. 抽象产品:电子设备接口
type ElectronicDevice interface {
PowerOn() // 开机方法
PowerOff() // 关机方法
}

// 2. 具体产品1:手机
type MobilePhone struct{}

func (m *MobilePhone) PowerOn() {
fmt.Println("手机开机,启动操作系统...")
}

func (m *MobilePhone) PowerOff() {
fmt.Println("手机关机,保存数据...")
}

// 2. 具体产品2:电脑
type Computer struct{}

func (c *Computer) PowerOn() {
fmt.Println("电脑开机,加载驱动程序...")
}

func (c *Computer) PowerOff() {
fmt.Println("电脑关机,关闭后台进程...")
}

// 3. 抽象工厂:电子设备工厂接口
type ElectronicDeviceFactory interface {
CreateDevice() ElectronicDevice // 创建产品方法
}

// 4. 具体工厂1:手机工厂
type MobilePhoneFactory struct{}

func (m *MobilePhoneFactory) CreateDevice() ElectronicDevice {
fmt.Println("手机工厂:创建手机实例")
return &MobilePhone{}
}

// 4. 具体工厂2:电脑工厂
type ComputerFactory struct{}

func (c *ComputerFactory) CreateDevice() ElectronicDevice {
fmt.Println("电脑工厂:创建电脑实例")
return &Computer{}
}

// 客户端调用
func main() {
// 获取手机产品
var mobileFactory ElectronicDeviceFactory = &MobilePhoneFactory{}
mobile := mobileFactory.CreateDevice()
mobile.PowerOn()
mobile.PowerOff()

// 获取电脑产品
var computerFactory ElectronicDeviceFactory = &ComputerFactory{}
computer := computerFactory.CreateDevice()
computer.PowerOn()
computer.PowerOff()
}

2.4 C++ 实现(纯虚函数+继承)

C++通过纯虚函数定义抽象接口(抽象产品、抽象工厂),结合继承实现具体产品与具体工厂,需注意虚析构函数的定义,避免内存泄漏,适合高性能、底层开发场景。

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
#include <iostream>
using namespace std;

// 1. 抽象产品:电子设备
class ElectronicDevice {
public:
// 纯虚函数:开机
virtual void PowerOn() = 0;
// 纯虚函数:关机
virtual void PowerOff() = 0;
// 虚析构函数,避免内存泄漏
virtual ~ElectronicDevice() {}
};

// 2. 具体产品1:手机
class MobilePhone : public ElectronicDevice {
public:
void PowerOn() override {
cout << "手机开机,启动操作系统..." << endl;
}

void PowerOff() override {
cout << "手机关机,保存数据..." << endl;
}
};

// 2. 具体产品2:电脑
class Computer : public ElectronicDevice {
public:
void PowerOn() override {
cout << "电脑开机,加载驱动程序..." << endl;
}

void PowerOff() override {
cout << "电脑关机,关闭后台进程..." << endl;
}
};

// 3. 抽象工厂:电子设备工厂
class ElectronicDeviceFactory {
public:
// 纯虚创建方法
virtual ElectronicDevice* CreateDevice() = 0;
// 虚析构函数
virtual ~ElectronicDeviceFactory() {}
};

// 4. 具体工厂1:手机工厂
class MobilePhoneFactory : public ElectronicDeviceFactory {
public:
ElectronicDevice* CreateDevice() override {
cout << "手机工厂:创建手机实例" << endl;
return new MobilePhone();
}
};

// 4. 具体工厂2:电脑工厂
class ComputerFactory : public ElectronicDeviceFactory {
public:
ElectronicDevice* CreateDevice() override {
cout << "电脑工厂:创建电脑实例" << endl;
return new Computer();
}
};

// 客户端调用
int main() {
// 获取手机产品
ElectronicDeviceFactory* mobileFactory = new MobilePhoneFactory();
ElectronicDevice* mobile = mobileFactory->CreateDevice();
mobile->PowerOn();
mobile->PowerOff();

// 获取电脑产品
ElectronicDeviceFactory* computerFactory = new ComputerFactory();
ElectronicDevice* computer = computerFactory->CreateDevice();
computer->PowerOn();
computer->PowerOff();

// 释放内存,避免泄漏
delete mobile;
delete mobileFactory;
delete computer;
delete computerFactory;

return 0;
}

2.5 纯C语言实现(结构体+函数指针)

纯C语言无面向对象特性,通过“结构体嵌套+函数指针”模拟抽象接口与继承,核心是将产品行为、工厂创建逻辑封装为函数指针,实现类似多态的效果,适合底层嵌入式开发。

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
#include <stdio.h>
#include <stdlib.h>

// 1. 抽象产品:电子设备(结构体+函数指针模拟抽象方法)
typedef struct _ElectronicDevice {
void (*PowerOn)(struct _ElectronicDevice*); // 开机函数指针
void (*PowerOff)(struct _ElectronicDevice*); // 关机函数指针
} ElectronicDevice;

// 2. 具体产品1:手机
typedef struct _MobilePhone {
ElectronicDevice base; // 嵌套基结构体,模拟继承
} MobilePhone;

// 手机的开机实现
void MobilePhone_PowerOn(ElectronicDevice* device) {
printf("手机开机,启动操作系统...\n");
}

// 手机的关机实现
void MobilePhone_PowerOff(ElectronicDevice* device) {
printf("手机关机,保存数据...\n");
}

// 2. 具体产品2:电脑
typedef struct _Computer {
ElectronicDevice base; // 嵌套基结构体,模拟继承
} Computer;

// 电脑的开机实现
void Computer_PowerOn(ElectronicDevice* device) {
printf("电脑开机,加载驱动程序...\n");
}

// 电脑的关机实现
void Computer_PowerOff(ElectronicDevice* device) {
printf("电脑关机,关闭后台进程...\n");
}

// 3. 抽象工厂:电子设备工厂(结构体+函数指针模拟创建方法)
typedef struct _ElectronicDeviceFactory {
ElectronicDevice* (*CreateDevice)(struct _ElectronicDeviceFactory*);
} ElectronicDeviceFactory;

// 4. 具体工厂1:手机工厂
typedef struct _MobilePhoneFactory {
ElectronicDeviceFactory base; // 嵌套基结构体,模拟继承
} MobilePhoneFactory;

// 手机工厂创建手机实例
ElectronicDevice* MobilePhoneFactory_CreateDevice(ElectronicDeviceFactory* factory) {
printf("手机工厂:创建手机实例\n");
MobilePhone* mobile = (MobilePhone*)malloc(sizeof(MobilePhone));
// 绑定函数指针(实现抽象方法)
mobile->base.PowerOn = MobilePhone_PowerOn;
mobile->base.PowerOff = MobilePhone_PowerOff;
return (ElectronicDevice*)mobile;
}

// 4. 具体工厂2:电脑工厂
typedef struct _ComputerFactory {
ElectronicDeviceFactory base; // 嵌套基结构体,模拟继承
} ComputerFactory;

// 电脑工厂创建电脑实例
ElectronicDevice* ComputerFactory_CreateDevice(ElectronicDeviceFactory* factory) {
printf("电脑工厂:创建电脑实例\n");
Computer* computer = (Computer*)malloc(sizeof(Computer));
// 绑定函数指针(实现抽象方法)
computer->base.PowerOn = Computer_PowerOn;
computer->base.PowerOff = Computer_PowerOff;
return (ElectronicDevice*)computer;
}

// 客户端调用
int main() {
// 1. 获取手机产品
MobilePhoneFactory mobileFactory;
mobileFactory.base.CreateDevice = MobilePhoneFactory_CreateDevice;
ElectronicDevice* mobile = mobileFactory.base.CreateDevice((ElectronicDeviceFactory*)&mobileFactory);
mobile->PowerOn(mobile);
mobile->PowerOff(mobile);

// 2. 获取电脑产品
ComputerFactory computerFactory;
computerFactory.base.CreateDevice = ComputerFactory_CreateDevice;
ElectronicDevice* computer = computerFactory.base.CreateDevice((ElectronicDeviceFactory*)&computerFactory);
computer->PowerOn(computer);
computer->PowerOff(computer);

// 释放内存
free(mobile);
free(computer);

return 0;
}

三、工厂方法模式的优缺点

工厂方法模式是在简单工厂模式基础上的优化,解决了简单工厂“扩展需修改代码”的核心问题,但同时也带来了一定的复杂度,需结合场景合理选择。

3.1 优点

  • 符合开闭原则:新增产品时,仅需新增具体产品类和对应具体工厂类,无需修改原有抽象工厂、已有工厂及客户端代码,降低扩展成本。

  • 解耦创建与使用:客户端仅依赖抽象工厂和抽象产品,无需了解产品的具体创建逻辑(如实例化细节、初始化步骤),降低代码耦合度。

  • 支持多态扩展:通过抽象接口实现多态,具体工厂可灵活返回不同的具体产品,客户端无需修改代码即可使用新的产品。

  • 责任单一:每个具体工厂仅负责创建一种具体产品,符合单一职责原则,便于代码维护和调试。

3.2 缺点

  • 增加系统复杂度:每新增一个产品,需同时新增具体产品类和具体工厂类,导致系统类数量增多,增加代码量和维护成本。

  • 层级冗余:相比简单工厂模式,多了抽象工厂和具体工厂的分层,对于简单场景(产品类型极少、无需扩展),显得过于繁琐。

  • 理解成本提升:需理解抽象接口、多态等概念,对于新手而言,上手难度高于简单工厂模式。

四、工厂方法模式的使用场景

工厂方法模式适合“产品类型需灵活扩展、需隐藏创建细节”的场景,具体应用如下:

  • 产品类型稳定且需扩展:如电商系统的支付方式(支付宝、微信支付、银行卡支付),新增支付方式时,仅需新增支付产品类和支付工厂类,无需修改原有支付逻辑。

  • 隐藏产品创建细节:如数据库连接池、日志管理器,客户端无需关心连接/日志实例的创建、初始化、销毁细节,仅通过工厂获取实例即可。

  • 框架/库设计:框架开发中,为了让用户能扩展自定义产品,通常会提供抽象工厂接口,用户通过实现具体工厂和产品,集成到框架中(如.NET的HandlerFactory、Spring的BeanFactory)。

  • 多环境适配:如不同环境(开发、测试、生产)的配置实例创建,通过不同的具体工厂,返回适配对应环境的配置产品,客户端无需修改代码即可切换环境。

注意:若产品类型极少(如仅1-2种)且无需扩展,建议使用简单工厂模式;若需支持多系列产品(如手机+电脑+平板,每种产品又有不同品牌),建议使用抽象工厂模式。

五、总结

工厂方法模式的核心是“抽象化创建逻辑,通过多态实现扩展”,其本质是将对象创建的责任委托给具体工厂,实现“创建与使用分离”,核心价值在于满足开闭原则,提升系统的灵活性和可维护性。

从多语言实现来看,尽管不同语言的语法差异显著,但核心思想完全一致:

  • 面向对象语言(C#、Python、Golang、C++):通过接口/抽象类定义规范,结合继承/结构体实现具体逻辑,利用多态特性实现扩展,贴合模式原生设计。

  • 纯C语言:通过结构体嵌套+函数指针模拟面向对象的继承和多态,核心是封装行为和创建逻辑,满足底层开发的需求。

在实际开发中,选择工厂方法模式的关键的是“判断产品是否需要扩展”:若产品固定不变,简单工厂模式更简洁;若产品需灵活扩展,工厂方法模式是更优选择。同时,需权衡系统复杂度与扩展性,避免过度设计——无需为了使用设计模式而强行引入分层,适合的场景才是最好的。