MST

星途 面试题库

面试题:Go语言结构体嵌套与组合在设计模式中的应用

设计一个包含多个嵌套结构体的Go程序,模拟一个电商系统中的订单模块。要求使用组合的方式,实现订单的创建、计算总价以及序列化订单信息的功能,同时阐述这种设计方式如何体现了设计模式中的某种原则(如开闭原则)。
42.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
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))
}

设计方式体现开闭原则的阐述

  1. 开闭原则定义:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。即当软件需要变化时,应该通过扩展代码来实现变化,而不是修改现有代码。
  2. 体现方式
    • 对扩展开放:在这个电商订单模块设计中,如果要添加新的功能,比如对某些商品添加折扣计算。可以通过在Product结构体中添加新的字段(如折扣率Discount),并在CalculateTotalPrice方法中添加相应的折扣计算逻辑,而不需要修改Order结构体和CreateOrder等现有函数的核心逻辑。同时,在序列化时,新添加的字段也会自动被处理(因为json.MarshalIndent会处理结构体的所有公开字段)。
    • 对修改关闭:原有的订单创建、计算总价和序列化功能的代码,在添加新功能时不需要直接修改。例如,当添加商品折扣功能时,CreateOrder函数创建订单的逻辑没有改变,Serialize函数的序列化逻辑也没有改变,只在需要扩展功能的地方(如CalculateTotalPrice函数中关于价格计算部分)进行了扩展。这样的设计方式使得系统在面对需求变化时,更容易维护和扩展,符合开闭原则。