package main
import (
"encoding/json"
"fmt"
)
// 商品结构体
type Product struct {
Name string
Price float64
Count int
}
// 订单详情结构体,组合商品结构体
type OrderItem struct {
Product Product
}
// 订单结构体,组合订单详情结构体
type Order struct {
Items []OrderItem
}
// 创建订单
func CreateOrder(items []OrderItem) *Order {
return &Order{Items: items}
}
// 计算订单总价
func (o *Order) CalculateTotalPrice() float64 {
total := 0.0
for _, item := range o.Items {
total += item.Product.Price * float64(item.Product.Count)
}
return total
}
// 序列化订单信息
func (o *Order) Serialize() ([]byte, error) {
return json.MarshalIndent(o, "", " ")
}
func main() {
product1 := Product{Name: "手机", Price: 5000, Count: 1}
product2 := Product{Name: "耳机", Price: 500, Count: 2}
item1 := OrderItem{Product: product1}
item2 := OrderItem{Product: product2}
order := CreateOrder([]OrderItem{item1, item2})
totalPrice := order.CalculateTotalPrice()
fmt.Printf("订单总价: %.2f\n", totalPrice)
serialized, err := order.Serialize()
if err != nil {
fmt.Println("序列化错误:", err)
return
}
fmt.Println("序列化订单信息:\n", string(serialized))
}
设计方式体现开闭原则的阐述
- 开闭原则定义:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。即当软件需要变化时,应该通过扩展代码来实现变化,而不是修改现有代码。
- 体现方式:
- 对扩展开放:在这个电商订单模块设计中,如果要添加新的功能,比如对某些商品添加折扣计算。可以通过在
Product
结构体中添加新的字段(如折扣率Discount
),并在CalculateTotalPrice
方法中添加相应的折扣计算逻辑,而不需要修改Order
结构体和CreateOrder
等现有函数的核心逻辑。同时,在序列化时,新添加的字段也会自动被处理(因为json.MarshalIndent
会处理结构体的所有公开字段)。
- 对修改关闭:原有的订单创建、计算总价和序列化功能的代码,在添加新功能时不需要直接修改。例如,当添加商品折扣功能时,
CreateOrder
函数创建订单的逻辑没有改变,Serialize
函数的序列化逻辑也没有改变,只在需要扩展功能的地方(如CalculateTotalPrice
函数中关于价格计算部分)进行了扩展。这样的设计方式使得系统在面对需求变化时,更容易维护和扩展,符合开闭原则。