ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 系统 ### 自动售货机 自动售货机可处于 4 种不同的状态中 * 有商品(has­Item) * 无商品(no­Item) * 商品已请求(item­Requested) * 收到纸币(has­Money) 自动售货机也会有不同的操作 * 选择商品 * 添加商品 * 插入纸币 * 提供商品 自动售货机可以有多种不同的状态,同时会在这些状态之间持续不断地互相转换。我们假设自动售货机处于`商品已请求`状态中。在“插入纸币”的操作发生后,机器将自动转换至`收到纸币`状态。 根据其当前状态,机器可就相同请求采取不同的行为。例如,如果用户想要购买一件商品,机器将在`有商品`状态时继续操作,而在`无商品`状态时拒绝操作 <details> <summary>main.go</summary> ``` // 不同的 state 分别实接口的4种情况的处理流程 package main import ( "fmt" "log" ) // 自动售货 type vendingMachine struct { hasItem state // 有商品 itemRequested state // 商品已请求 hasMoney state // 插入纸币 noItem state // 收到纸币 currentState state itemCount int itemPrice int } func newVendingMachine(itemCount, itemPrice int) *vendingMachine { v := &vendingMachine{ itemCount: itemCount, itemPrice: itemPrice, } hasItemState := &hasItemState{ vendingMachine: v, } itemRequestedState := &itemRequestedState{ vendingMachine: v, } hasMoneyState := &hasMoneyState{ vendingMachine: v, } noItemState := &noItemState{ vendingMachine: v, } v.setState(hasItemState) v.hasItem = hasItemState v.itemRequested = itemRequestedState v.hasMoney = hasMoneyState v.noItem = noItemState return v } func (v *vendingMachine) requestItem() error { return v.currentState.requestItem() } func (v *vendingMachine) addItem(count int) error { return v.currentState.addItem(count) } func (v *vendingMachine) insertMoney(money int) error { return v.currentState.insertMoney(money) } func (v *vendingMachine) dispenseItem() error { return v.currentState.dispenseItem() } func (v *vendingMachine) setState(s state) { v.currentState = s } func (v *vendingMachine) incrementItemCount(count int) { fmt.Printf("Adding %d items\n", count) v.itemCount = v.itemCount + count } // 状态接口,声明不通状态下的操作 type state interface { addItem(int) error // 选择商品 requestItem() error // 添加商品 insertMoney(money int) error // 插入纸币 dispenseItem() error // 送货 } // 有商品 type hasItemState struct { vendingMachine *vendingMachine } func (i *hasItemState) requestItem() error { // 切换到无商品模式 if i.vendingMachine.itemCount == 0 { i.vendingMachine.setState(i.vendingMachine.noItem) return fmt.Errorf("No item present") } fmt.Printf("Item requestd\n") i.vendingMachine.setState(i.vendingMachine.itemRequested) return nil } func (i *hasItemState) addItem(count int) error { fmt.Printf("%d items added\n", count) i.vendingMachine.incrementItemCount(count) return nil } func (i *hasItemState) insertMoney(money int) error { return fmt.Errorf("请先选择项目") } func (i *hasItemState) dispenseItem() error { return fmt.Errorf("请先选择项目") } // 没商品 type noItemState struct { vendingMachine *vendingMachine } func (i *noItemState) requestItem() error { return fmt.Errorf("商品缺货") } // 添加商品,切换为有商品状态 func (i *noItemState) addItem(count int) error { i.vendingMachine.incrementItemCount(count) i.vendingMachine.setState(i.vendingMachine.hasItem) return nil } func (i *noItemState) insertMoney(money int) error { return fmt.Errorf("商品缺货") } func (i *noItemState) dispenseItem() error { return fmt.Errorf("商品缺货") } // 商品已请求 type itemRequestedState struct { vendingMachine *vendingMachine } func (i *itemRequestedState) requestItem() error { return fmt.Errorf("物品已被要求") } func (i *itemRequestedState) addItem(count int) error { return fmt.Errorf("项目分配过程中") } func (i *itemRequestedState) insertMoney(money int) error { if money < i.vendingMachine.itemPrice { _ = fmt.Errorf("插入的钱更少。请插入 %d", i.vendingMachine.itemPrice) } fmt.Println("Money entered is ok") i.vendingMachine.setState(i.vendingMachine.hasMoney) return nil } func (i *itemRequestedState) dispenseItem() error { return fmt.Errorf("请先插入钱") } // 收到货币 type hasMoneyState struct { vendingMachine *vendingMachine } func (i *hasMoneyState) requestItem() error { return fmt.Errorf("正在进行物品分配") } func (i *hasMoneyState) addItem(count int) error { return fmt.Errorf("正在进行物品分配") } func (i *hasMoneyState) insertMoney(money int) error { return fmt.Errorf("商品缺货") } func (i *hasMoneyState) dispenseItem() error { fmt.Println("Dispensing Item") i.vendingMachine.itemCount -- if i.vendingMachine.itemCount == 0 { i.vendingMachine.setState(i.vendingMachine.noItem) } else { i.vendingMachine.setState(i.vendingMachine.hasItem) } return nil } func main() { // 初始化商品, 数量1 ,价格10 vendingMachine := newVendingMachine(1, 10) err := vendingMachine.requestItem() if err != nil { log.Fatalf(err.Error()) } // 2020/09/30 23:21:51 请先插入钱 //err= vendingMachine.dispenseItem() //if err != nil { // log.Fatalf(err.Error()) //} err = vendingMachine.insertMoney(10) if err != nil { log.Fatalf(err.Error()) } err = vendingMachine.dispenseItem() if err != nil { log.Fatalf(err.Error()) } fmt.Println() err = vendingMachine.addItem(2) if err != nil { log.Fatalf(err.Error()) } fmt.Println() err = vendingMachine.requestItem() if err != nil { log.Fatalf(err.Error()) } err = vendingMachine.insertMoney(10) if err != nil { log.Fatalf(err.Error()) } err = vendingMachine.dispenseItem() if err != nil { log.Fatalf(err.Error()) } } ``` </details> <br /> 输出 ``` Item requestd Money entered is ok Dispensing Item Adding 2 items Item requestd Money entered is ok Dispensing Item ```