文章目錄
- Go語言中的組合式接口設計模式
- 背景和需求
- 組合式接口設計
Go語言中的組合式接口設計模式
背景和需求
在微服務架構和復雜業務系統中,我們經常需要調用多個外部服務或內部模塊。傳統的做法是將所有方法都放在一個大接口中,但這種設計會導致接口臃腫、職責不清。今天我們來探討一種更優雅的設計模式:組合式接口設計。
問題場景
假設我們正在開發一個電商系統,需要集成多個服務:
- 支付服務:處理支付、退款等
- 物流服務:查詢物流、發貨等
- 用戶服務:用戶信息管理
- 商品服務:商品信息管理
傳統設計的問題
// 傳統的混合接口設計(不推薦)
type ExternalAPI interface {// 支付相關CreatePayment(ctx context.Context, order *Order) (*Payment, error)RefundPayment(ctx context.Context, paymentID string) error// 物流相關CreateShipment(ctx context.Context, order *Order) (*Shipment, error)TrackShipment(ctx context.Context, trackingID string) (*TrackingInfo, error)// 用戶相關GetUserProfile(ctx context.Context, userID string) (*User, error)UpdateUserProfile(ctx context.Context, user *User) error// 商品相關GetProductInfo(ctx context.Context, productID string) (*Product, error)UpdateProductStock(ctx context.Context, productID string, stock int) error
}
傳統方式:
// 不清楚這些方法來自哪個服務
api.CreatePayment(ctx, order)
api.TrackShipment(ctx, trackingID)
api.GetUserProfile(ctx, userID)
組合式接口設計
// 主接口:服務聚合器
type ExternalAPI interface {Payment() PaymentServiceLogistics() LogisticsServiceUser() UserServiceProduct() ProductService
}// 支付服務接口
type PaymentService interface {CreatePayment(ctx context.Context, order *Order) (*Payment, error)RefundPayment(ctx context.Context, paymentID string) errorGetPaymentStatus(ctx context.Context, paymentID string) (*PaymentStatus, error)
}// 物流服務接口
type LogisticsService interface {CreateShipment(ctx context.Context, order *Order) (*Shipment, error)TrackShipment(ctx context.Context, trackingID string) (*TrackingInfo, error)CancelShipment(ctx context.Context, shipmentID string) error
}// 用戶服務接口
type UserService interface {GetUserProfile(ctx context.Context, userID string) (*User, error)UpdateUserProfile(ctx context.Context, user *User) errorGetUserOrders(ctx context.Context, userID string) ([]*Order, error)
}// 商品服務接口
type ProductService interface {GetProductInfo(ctx context.Context, productID string) (*Product, error)UpdateProductStock(ctx context.Context, productID string, stock int) errorSearchProducts(ctx context.Context, query string) ([]*Product, error)
}
組合式設計:
// 清晰的服務邊界和調用意圖
api.Payment().CreatePayment(ctx, order)
api.Logistics().TrackShipment(ctx, trackingID)
api.User().GetUserProfile(ctx, userID)
通過這種設計,我們不僅提高了代碼的可維護性,還讓團隊協作變得更加高效——每個開發者都能清楚地知道自己在調用哪個服務的哪個功能。
接口定義改變:從混合接口變為組合接口