package main
import "fmt"
// Product结构体表示商品
type Product struct {
id int
name string
price float64
}
// OrderItem结构体表示订单中的商品项
type OrderItem struct {
product Product
quantity int
}
// Order结构体表示订单
type Order struct {
orderId int
customer string
items []OrderItem
discountCalculator DiscountCalculator
}
// DiscountCalculator接口用于计算折扣
type DiscountCalculator interface {
CalculateDiscount(order Totalizable) float64
}
// Totalizable接口用于获取订单总价
type Totalizable interface {
Total() float64
}
// Order实现Totalizable接口
func (o Order) Total() float64 {
total := 0.0
for _, item := range o.items {
total += item.product.price * float64(item.quantity)
}
return total
}
// CalculateTotal方法计算订单总金额
func (o Order) CalculateTotal() float64 {
total := o.Total()
if o.discountCalculator != nil {
discount := o.discountCalculator.CalculateDiscount(o)
total -= discount
}
return total
}
// FixedDiscountCalculator结构体用于固定金额满减折扣
type FixedDiscountCalculator struct {
threshold float64
discount float64
}
// CalculateDiscount方法计算固定金额满减折扣
func (f FixedDiscountCalculator) CalculateDiscount(order Totalizable) float64 {
total := order.Total()
if total >= f.threshold {
return f.discount
}
return 0
}
// PercentageDiscountCalculator结构体用于百分比折扣
type PercentageDiscountCalculator struct {
percentage float64
}
// CalculateDiscount方法计算百分比折扣
func (p PercentageDiscountCalculator) CalculateDiscount(order Totalizable) float64 {
total := order.Total()
return total * p.percentage
}
扩展性优势
- 接口抽象:通过
DiscountCalculator
接口,将折扣计算逻辑抽象出来。如果需要添加新的折扣类型(如阶梯折扣、限时折扣等),只需创建一个新的结构体实现 DiscountCalculator
接口即可,无需修改原有的订单计算逻辑。
- 组合方式:
Order
结构体中组合了 DiscountCalculator
接口类型的字段,这样可以在运行时动态地设置不同的折扣计算方式,提高了灵活性。
维护性优势
- 单一职责原则:每个结构体和接口都有明确的职责。例如,
Product
结构体负责商品信息,Order
结构体负责订单信息和总金额计算,折扣计算逻辑由实现 DiscountCalculator
接口的结构体负责。这样在修改或扩展某一部分功能时,不会影响到其他部分。
- 代码可读性:结构清晰,各个部分的功能一目了然。例如,
CalculateTotal
方法的逻辑简单明了,先计算总价,再根据折扣计算器计算折扣并扣除,易于理解和维护。