状态模式:允许对象在内部状态改变时改变它的行为,对象看起来修改了它的类。
package state
import (
"fmt"
)
type State interface {
InsertQuarter(machine *GumballMachine)
EjectQuarter(machine *GumballMachine)
TurnCrank(machine *GumballMachine)
Dispense(machine *GumballMachine)
}
type GumballMachine struct {
state State
count int
soldOutState State
noQuarterState State
hasQuarterState State
soldState State
}
func (o *GumballMachine) SetState(state State) {
o.state = state
}
func (o *GumballMachine) ReleaseBall() {
fmt.Println("a gumball comes rolling out the slot...")
if o.count != 0 {
o.count = o.count - 1
}
}
func (o *GumballMachine) InsertQuarter() {
o.state.InsertQuarter(o)
}
func (o *GumballMachine) EjectQuarter() {
o.state.EjectQuarter(o)
}
func (o *GumballMachine) TurnCrank() {
o.state.TurnCrank(o)
}
func NewMachine() *GumballMachine {
return &GumballMachine{
state: &NoQuarterState{},
count: 10,
soldOutState: &SoldOutState{},
soldState: &SoldState{},
hasQuarterState: &HasQuarterState{},
noQuarterState: &NoQuarterState{},
}
}
type NoQuarterState struct {
}
type HasQuarterState struct {
}
type SoldOutState struct {
}
type SoldState struct {
}
func (NoQuarterState) InsertQuarter(machine *GumballMachine) {
fmt.Println("You inserted a quarter")
machine.SetState(machine.hasQuarterState)
}
func (NoQuarterState) EjectQuarter(machine *GumballMachine) {
fmt.Println("You have not inserted a quarter")
}
func (NoQuarterState) TurnCrank(machine *GumballMachine) {
fmt.Println("You have not inserted a quarter")
}
func (NoQuarterState) Dispense(machine *GumballMachine) {
fmt.Println("You have not inserted a quarter")
}
func (*SoldState) InsertQuarter(machine *GumballMachine) {
fmt.Println("Please wait, we are already giving you a gumbail")
}
func (*SoldState) EjectQuarter(machine *GumballMachine) {
fmt.Println("Sorry, you already turned the crank")
}
func (*SoldState) TurnCrank(machine *GumballMachine) {
fmt.Println("turning twice does not get you another gumball")
}
func (*SoldState) Dispense(machine *GumballMachine) {
machine.ReleaseBall()
if machine.count > 0 {
machine.SetState(machine.noQuarterState)
} else {
machine.SetState(machine.soldOutState)
}
}
func (*SoldOutState) InsertQuarter(machine *GumballMachine) {
}
func (*SoldOutState) EjectQuarter(machine *GumballMachine) {
}
func (*SoldOutState) TurnCrank(machine *GumballMachine) {
}
func (*SoldOutState) Dispense(machine *GumballMachine) {
}
func (*HasQuarterState) InsertQuarter(machine *GumballMachine) {
}
func (*HasQuarterState) EjectQuarter(machine *GumballMachine) {
}
func (*HasQuarterState) TurnCrank(machine *GumballMachine) {
}
func (*HasQuarterState) Dispense(machine *GumballMachine) {
}