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() PaymentService
Logistics() LogisticsService
User() UserService
Product() ProductService
}
// 支付服务接口
type PaymentService interface {
CreatePayment(ctx context.Context, order *Order) (*Payment, error)
RefundPayment(ctx context.Context, paymentID string) error
GetPaymentStatus(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) error
GetUserOrders(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) error
SearchProducts(ctx context.Context, query string) ([]*Product, error)
}
组合式设计:
// 清晰的服务边界和调用意图
api.Payment().CreatePayment(ctx, order)
api.Logistics().TrackShipment(ctx, trackingID)
api.User().GetUserProfile(ctx, userID)
通过这种设计,我们不仅提高了代码的可维护性,还让团队协作变得更加高效——每个开发者都能清楚地知道自己在调用哪个服务的哪个功能。
接口定义改变:从混合接口变为组合接口