参考:【设计模式专题之单例模式】1.小明的购物车
【设计模式专题之单例模式】
1.小明的购物车 时间限制:1.000S 空间限制:256MB
题目描述
小明去了一家大型商场,拿到了一个购物车,并开始购物。请你设计一个购物车管理器,记录商品添加到购物车的信息(商品名称和购买数量),并在购买结束后打印出商品清单。(在整个购物过程中,小明只有一个购物车实例存在)。
输入描述
输入包含若干行,每行包含两部分信息,分别是商品名称和购买数量。商品名称和购买数量之间用空格隔开。
输出描述
输出包含小明购物车中的所有商品及其购买数量。每行输出一种商品的信息,格式为 “商品名称 购买数量”。
输入示例
Apple 3 Banana 2 Orange 5
输出示例
Apple 3 Banana 2 Orange 5
提示信息
- 本道题目请使用单例设计模式
- 使用私有静态变量来保存购物车实例
- 使用私有构造函数防止外部直接实例化
思路:
- 单例实现,借助Golang中的 sync.Once 包 和 全局变量 实现
- 先实现几个必要结构、实例和方法,结构体 如:商品信息、购物车信息;实例 如:购物车实例;方法 如:
Set
和Get
方法。
注意:
Set
方法,需要修改接收器指向的购物车中的商品信息,因此需要使用指针接收器Get
方法,需要读取购物车中的商品信息,无需修改,所以可以使用值接收器。这样在调用Get方法时,会创建接收器的副本,而不会影响原始购物车实例。main
方法,外部自定义格式的输入方式,应由外部处理,而不应放入Set方法中处理,避免Set方法因外部输入格式变动而频繁改动
Golang版本代码:
package mainimport (
"fmt"
"sync"
)// 单例 全局变量
var (instance *ShoppingCartInfoonce sync.Once
)// ProductInfo 商品信息
type ProductInfo struct {Name stringQuantity int
}// ShoppingCart 购物车信息
type ShoppingCartInfo struct {shoppingCart []ProductInfo
}// NewInstance 新建购物车实例
func NewInstance() *ShoppingCartInfo {once.Do(func() {instance = &ShoppingCartInfo{shoppingCart: make([]ProductInfo, 0),}})return instance
}// Set 添加购物车商品信息
// Set方法,需要修改接收器指向的购物车中的商品信息,因此需要使用指针接收器
func (m *ShoppingCartInfo) Set(info ProductInfo) {m.shoppingCart = append(m.shoppingCart, info)
}// Get 获取购物车商品信息
// Get方法,需要读取购物车中的商品信息,无需修改,所以可以使用值接收器。
// 这样在调用Get方法时,会创建接收器的副本,而不会影响原始购物车实例。
func (m ShoppingCartInfo) Get() {for _, info := range m.shoppingCart {fmt.Println(info.Name, info.Quantity)}
}// main
func main() {ins := NewInstance()name, quantity := "", 0// 模拟多次添加购物车商品for {// 外部自定义格式的输入方式,应由外部处理,而不应放入Set方法中处理,避免Set方法因外部输入格式变动而频繁改动if _, err := fmt.Scanf("%s %d", &name, &quantity); err != nil {break}ins.Set(ProductInfo{Name: name,Quantity: quantity,})}// 最后一次性获取购物车所有商品信息ins.Get()
}