package main
import (
"fmt"
)
// 状态接口
type State interface {
InsertCoin(machine *VendingMachine)
SelectProduct(machine *VendingMachine)
DispenseProduct(machine *VendingMachine)
}
// 等待投币状态
type WaitingForCoin struct{}
func (w *WaitingForCoin) InsertCoin(machine *VendingMachine) {
fmt.Println("硬币已投入,进入已投币可选择商品状态")
machine.State = &CoinInserted{}
}
func (w *WaitingForCoin) SelectProduct(machine *VendingMachine) {
fmt.Println("请先投入硬币")
}
func (w *WaitingForCoin) DispenseProduct(machine *VendingMachine) {
fmt.Println("请先投入硬币并选择商品")
}
// 已投币可选择商品状态
type CoinInserted struct{}
func (c *CoinInserted) InsertCoin(machine *VendingMachine) {
fmt.Println("已经投币,无需再次投币")
}
func (c *CoinInserted) SelectProduct(machine *VendingMachine) {
fmt.Println("商品已选择,进入出货中状态")
machine.State = &Dispensing{}
}
func (c *CoinInserted) DispenseProduct(machine *VendingMachine) {
fmt.Println("请先选择商品")
}
// 出货中状态
type Dispensing struct{}
func (d *Dispensing) InsertCoin(machine *VendingMachine) {
fmt.Println("正在出货,请勿投币")
}
func (d *Dispensing) SelectProduct(machine *VendingMachine) {
fmt.Println("正在出货,请勿选择商品")
}
func (d *Dispensing) DispenseProduct(machine *VendingMachine) {
fmt.Println("商品已出货,回到等待投币状态")
machine.State = &WaitingForCoin{}
}
// 自动售货机
type VendingMachine struct {
State State
}
func NewVendingMachine() *VendingMachine {
return &VendingMachine{
State: &WaitingForCoin{},
}
}
代码解释
- 状态接口(State):定义了状态机中每个状态都需要实现的方法,包括
InsertCoin
(投币)、SelectProduct
(选择商品)和 DispenseProduct
(出货)。
- 等待投币状态(WaitingForCoin):实现了
State
接口。在该状态下,只有投币操作能使状态机进入“已投币可选择商品”状态,其他操作提示相应错误。
- 已投币可选择商品状态(CoinInserted):同样实现
State
接口。在此状态下,投币操作提示无需投币,选择商品操作使状态机进入“出货中”状态,出货操作提示先选择商品。
- 出货中状态(Dispensing):实现
State
接口。在这个状态下,投币和选择商品操作都被禁止,出货完成后状态机回到“等待投币”状态。
- 自动售货机(VendingMachine):包含一个
State
类型的字段,代表当前状态机所处的状态。NewVendingMachine
函数初始化状态机为“等待投币”状态。通过调用不同状态下的方法,实现状态机在不同状态间的正确切换。