2、工厂模式

工厂模式(Factory)提供了一种创建对象的接口,允许子类决定实例化的对象类型。在Go中,可以通过函数和接口实现工厂模式:

定义

package payment

import "fmt"

// PaymentMethod接口定义了支付方法的行为
type PaymentMethod interface {
    Pay(amount float64) bool
    GetName() string
}

// CreditCard实现PaymentMethod接口
type CreditCard struct {
    cardNumber string
    cvv        string
    expiry     string
}

func (c CreditCard) Pay(amount float64) bool {
    fmt.Printf("使用信用卡支付%.2f元\n", amount)
    return true
}

func (c CreditCard) GetName() string {
    return "信用卡"
}

// Alipay实现PaymentMethod接口
type Alipay struct {
    accountID string
}

func (a Alipay) Pay(amount float64) bool {
    fmt.Printf("使用支付宝支付%.2f元\n", amount)
    return true
}

func (a Alipay) GetName() string {
    return "支付宝"
}

// WechatPay实现PaymentMethod接口
type WechatPay struct {
    accountID string
}

func (w WechatPay) Pay(amount float64) bool {
    fmt.Printf("使用微信支付%.2f元\n", amount)
    return true
}

func (w WechatPay) GetName() string {
    return "微信支付"
}

// 支付方式类型
type PaymentType string

const (
    CreditCardType PaymentType = "credit_card"
    AlipayType     PaymentType = "alipay"
    WechatPayType  PaymentType = "wechat_pay"
)

// CreatePaymentMethod是一个工厂函数,根据类型创建支付方法
func CreatePaymentMethod(payType PaymentType) (PaymentMethod, error) {
    switch payType {
    case CreditCardType:
        return CreditCard{
            cardNumber: "1234-5678-9012-3456",
            cvv:        "123",
            expiry:     "12/25",
        }, nil
        
    case AlipayType:
        return Alipay{
            accountID: "alipay@example.com",
        }, nil
        
    case WechatPayType:
        return WechatPay{
            accountID: "wxid_12345",
        }, nil
        
    default:
        return nil, fmt.Errorf("不支持的支付方式: %s", payType)
    }
}

使用

// main.go
package main

import (
    "fmt"
    "myapp/payment"
)

func ProcessPayment(amount float64, payType payment.PaymentType) {
    method, err := payment.CreatePaymentMethod(payType)
    if err != nil {
        fmt.Println("错误:", err)
        return
    }
    
    fmt.Printf("使用%s处理支付...\n", method.GetName())
    success := method.Pay(amount)
    
    if success {
        fmt.Println("支付成功!")
    } else {
        fmt.Println("支付失败!")
    }
}

func main() {
    ProcessPayment(199.99, payment.CreditCardType)
    ProcessPayment(299.99, payment.AlipayType)
    ProcessPayment(399.99, payment.WechatPayType)
    
    // 测试错误情况
    ProcessPayment(499.99, "unknown")
}