什么是工厂模式?
工厂模式是一种创建型设计模式,将对象的创建逻辑封装在“工厂”中,客户端无需关心具体实现。它的核心是创建与使用的分离,提高代码灵活性和可维护性。
工厂模式包括:
- 简单工厂:通过一个工厂根据参数创建对象。
- 工厂方法:定义工厂接口,由子类实现创建逻辑。
- 抽象工厂:创建一组相关对象的工厂。
核心要素:
适用场景:
- 根据条件创建不同对象(如支付方式)。
- 对象创建复杂(如需要配置)。
- 统一管理相关对象的创建。
为什么在 Go 中使用工厂模式?
Go 语言通过接口和结构体实现工厂模式,适用于:
- 支付系统:动态创建微信、支付宝支付对象。
- 数据库驱动:选择 MySQL、PostgreSQL 驱动。
- 消息队列:创建 Kafka、RabbitMQ 客户端。
本文通过一个支付系统的例子,展示工厂模式在 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
|
package payment
import (
"errors"
"fmt"
)
// Payment 接口,定义支付行为
type Payment interface {
Process(amount float64) (string, error) // 处理支付,返回交易ID
}
// WeChatPay 微信支付实现
type WeChatPay struct{}
func (w *WeChatPay) Process(amount float64) (string, error) {
if amount <= 0 {
return "", errors.New("invalid amount")
}
transactionID := fmt.Sprintf("WX-%d", time.Now().UnixNano())
return transactionID, nil
}
// AliPay 支付宝实现
type AliPay struct{}
func (a *AliPay) Process(amount float64) (string, error) {
if amount <= 0 {
return "", errors.New("invalid amount")
}
transactionID := fmt.Sprintf("ALI-%d", time.Now().UnixNano())
return transactionID, nil
}
// PaymentType 支付类型枚举
type PaymentType string
const (
WeChat PaymentType = "wechat"
AliPay PaymentType = "alipay"
)
// PaymentFactory 简单工厂函数
func PaymentFactory(paymentType PaymentType) (Payment, error) {
switch paymentType {
case WeChat:
return &WeChatPay{}, nil
case AliPay:
return &AliPay{}, nil
default:
return nil, fmt.Errorf("unsupported payment type: %s", paymentType)
}
}
|
使用示例
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
|
package main
import (
"fmt"
"yourmodule/payment"
)
func main() {
wechatPay, err := payment.PaymentFactory(payment.WeChat)
if err != nil {
fmt.Println("Error:", err)
return
}
transactionID, err := wechatPay.Process(100.50)
if err != nil {
fmt.Println("Payment failed:", err)
return
}
fmt.Println("WeChat Payment Success, Transaction ID:", transactionID)
aliPay, err := payment.PaymentFactory(payment.AliPay)
if err != nil {
fmt.Println("Error:", err)
return
}
transactionID, err = aliPay.Process(200.75)
if err != nil {
fmt.Println("Payment failed:", err)
return
}
fmt.Println("AliPay Payment Success, Transaction ID:", transactionID)
}
|
讲解
PaymentFactory
根据PaymentType
创建支付对象。
- 客户端通过工厂获取对象,无需直接实例化。
- 局限性:扩展需要修改
switch
语句。
工厂方法实现
工厂方法通过接口分散创建逻辑,每个支付方式对应一个工厂,增强扩展性。
代码实现
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
|
package payment
import (
"errors"
"fmt"
"time"
)
// Payment 接口,定义支付行为
type Payment interface {
Process(amount float64) (string, error)
}
// WeChatPay 微信支付
type WeChatPay struct{}
func (w *WeChatPay) Process(amount float64) (string, error) {
if amount <= 0 {
return "", errors.New("invalid amount")
}
return fmt.Sprintf("WX-%d", time.Now().UnixNano()), nil
}
// AliPay 支付宝
type AliPay struct{}
func (a *AliPay) Process(amount float64) (string, error) {
if amount <= 0 {
return "", errors.New("invalid amount")
}
return fmt.Sprintf("ALI-%d", time.Now().UnixNano()), nil
}
// PaymentFactory 工厂接口
type PaymentFactory interface {
CreatePayment() Payment
}
// WeChatPaymentFactory 微信支付工厂
type WeChatPaymentFactory struct{}
func (w *WeChatPaymentFactory) CreatePayment() Payment {
return &WeChatPay{}
}
// AliPayFactory 支付宝工厂
type AliPayFactory struct{}
func (a *AliPayFactory) CreatePayment() Payment {
return &AliPay{}
}
|
使用示例
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
|
package main
import (
"fmt"
"yourmodule/payment"
)
func main() {
wechatFactory := &payment.WeChatPaymentFactory{}
wechatPay := wechatFactory.CreatePayment()
transactionID, err := wechatPay.Process(100.50)
if err != nil {
fmt.Println("Payment failed:", err)
return
}
fmt.Println("WeChat Payment Success, Transaction ID:", transactionID)
aliFactory := &payment.AliPayFactory{}
aliPay := aliFactory.CreatePayment()
transactionID, err = aliPay.Process(200.75)
if err != nil {
fmt.Println("Payment failed:", err)
return
}
fmt.Println("AliPay Payment Success, Transaction ID:", transactionID)
}
|
讲解
- 每个支付方式有自己的工厂,符合“开闭原则”。
- 优势:扩展只需添加新工厂,无需修改现有代码。
抽象工厂实现
抽象工厂创建一组相关对象(如支付处理器和验证器),适合复杂场景。
代码实现
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
|
package payment
import (
"errors"
"fmt"
"sync"
"time"
)
// PaymentProcessor 处理支付
type PaymentProcessor interface {
Process(amount float64) (string, error)
}
// PaymentValidator 验证支付状态
type PaymentValidator interface {
Validate(transactionID string) (bool, error)
}
// WeChatProcessor 微信支付处理器
type WeChatProcessor struct {
mu sync.Mutex
transactions map[string]float64
}
func (w *WeChatProcessor) Process(amount float64) (string, error) {
if amount <= 0 {
return "", errors.New("invalid amount")
}
w.mu.Lock()
defer w.mu.Unlock()
transactionID := fmt.Sprintf("WX-%d", time.Now().UnixNano())
w.transactions[transactionID] = amount
return transactionID, nil
}
func (w *WeChatProcessor) Validate(transactionID string) (bool, error) {
w.mu.Lock()
defer w.mu.Unlock()
_, exists := w.transactions[transactionID]
return exists, nil
}
// AliPayProcessor 支付宝处理器
type AliPayProcessor struct {
mu sync.Mutex
transactions map[string]float64
}
func (a *AliPayProcessor) Process(amount float64) (string, error) {
if amount <= 0 {
return "", errors.New("invalid amount")
}
a.mu.Lock()
defer a.mu.Unlock()
transactionID := fmt.Sprintf("ALI-%d", time.Now().UnixNano())
a.transactions[transactionID] = amount
return transactionID, nil
}
func (a *AliPayProcessor) Validate(transactionID string) (bool, error) {
a.mu.Lock()
defer a.mu.Unlock()
_, exists := a.transactions[transactionID]
return exists, nil
}
// PaymentAbstractFactory 抽象工厂接口
type PaymentAbstractFactory interface {
CreateProcessor() PaymentProcessor
CreateValidator() PaymentValidator
}
// WeChatAbstractFactory 微信支付抽象工厂
type WeChatAbstractFactory struct{}
func (w *WeChatAbstractFactory) CreateProcessor() PaymentProcessor {
return &WeChatProcessor{transactions: make(map[string]float64)}
}
func (w *WeChatAbstractFactory) CreateValidator() PaymentValidator {
return &WeChatProcessor{transactions: make(map[string]float64)}
}
// AliPayAbstractFactory 支付宝抽象工厂
type AliPayAbstractFactory struct{}
func (a *AliPayAbstractFactory) CreateProcessor() PaymentProcessor {
return &AliPayProcessor{transactions: make(map[string]float64)}
}
func (a *AliPayAbstractFactory) CreateValidator() PaymentValidator {
return &AliPayProcessor{transactions: make(map[string]float64)}
}
|
使用示例
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
|
package main
import (
"fmt"
"yourmodule/payment"
)
func main() {
wechatFactory := &payment.WeChatAbstractFactory{}
processor := wechatFactory.CreateProcessor()
validator := wechatFactory.CreateValidator()
transactionID, err := processor.Process(100.50)
if err != nil {
fmt.Println("Payment failed:", err)
return
}
fmt.Println("WeChat Payment Success, Transaction ID:", transactionID)
valid, err := validator.Validate(transactionID)
if err != nil {
fmt.Println("Validation failed:", err)
return
}
fmt.Println("Transaction Valid:", valid)
aliFactory := &payment.AliPayAbstractFactory{}
processor = aliFactory.CreateProcessor()
transactionID, err = processor.Process(200.75)
if err != nil {
fmt.Println("Payment failed:", err)
return
}
fmt.Println("AliPay Payment Success, Transaction ID:", transactionID)
}
|
讲解
- 抽象工厂创建处理器和验证器,管理相关对象。
- 使用
sync.Mutex
确保并发安全。
- 优势:适合复杂系统,统一管理对象族。
常见问题
-
简单工厂和工厂方法区别?
简单工厂集中创建逻辑,扩展需修改代码;工厂方法分散逻辑,扩展性更好。
-
Go 中需要工厂模式吗?
在封装创建逻辑、支持扩展的场景中,工厂模式很有用。
-
如何处理并发?
使用sync.Mutex
或sync.Once
确保线程安全。
总结
工厂模式在 Go 中通过接口和结构体实现,适合支付系统等场景。本文展示了简单工厂、工厂方法和抽象工厂的实现,以及在支付系统中的应用。希望这篇文章帮助您掌握工厂模式!
欢迎留言:分享您在 Go 项目中使用工厂模式的经验!
评论 0