当前位置: 首页 > 科技观察

我是一个状态机,一个永远动荡不安的机器引擎

时间:2023-03-15 19:54:19 科技观察

转载请联系精益码农公众号。状态机是一种行为设计模式,允许对象在其内部状态发生变化时改变其行为。看起来好像对象改变了它的类。请仔细阅读上面的每一个字。我们以自动售货机为例。为了简化演示,我们假设自动售货机只有一种商品,所以自动售货机有两个属性:itemCount和itemPrice。不考虑动作的上下文相关性,自动售货机暴露了4个行为:向自动售货机添加商品addItem选择商品requestItemPayinginsertMoneyShippingdispenseItem关键是当某个行为发生时,自动售货机输入以下4个中的一个hasItemhasitem,noitemnoItemhasselecteditemitemRequestedpaidhasMoney当对象可能处于多种不同状态时1.改变当前state根据传入的action,继续接受后续的action,state再次发生变化……这种模式类似于一个机器引擎,重复工作,不断改变状态。这也是将状态机的定语称为“机器Machine”的原因。有了以上思路,我们尝试交流一下UML伪代码:状态机设计模式的伪代码实现:所谓机器机器维护状态切换的上下文机器暴露的行为驱动状态机的状态变化机器。行为和状态是因果关系当机器到达特定状态时,它只有特定的行为,其他行为是不允许的。从外面看,对象似乎改变了原始类的行为。下面使用golang实现状态机设计模型:也可以看这里golang在OOPgoodMachine中是如何体现类继承和接口实现的:itemPriceint)*goodMachine{v:=&goodMachine{itemCount:itemCount:itemPriceitemPrice,}ifitemCount<=0{v.setState(&noItemState{v})//状态接口的实现是*noItemState指针类型}else{v.setState(&hasItemState{v})}returnv}func(v*goodMachine)setState(sstate){fmt.Println("enterstate:",reflect.TypeOf(s))v.currentState=s}func(v*goodMachine)requestItem()error{returnv.currentState.requestItem()}func(v*goodMachine)addItem(countint)error{returnv.currentState.addItem(count)}func(v*goodMachine)insertMoney(moneyint)error{returnv.currentState.insertMoney(money)}func(v*goodMachine)incrementItemCount(countint){v.itemCount+=count}func(vgoodMachine)dispenseItem()error{returnv.currentState.dispenseItem()}自动售货机的外部行为委托给一个特定的状态对象state:自动售货机暴露给外界Behaviorpackagemain//表示某种状态,可接受的action匿名类型goodMachine,类型为*goodMachine}//为自动售货机供应----->库存状态func(i*noItemState)addItem(countint)error{i.incrementItemCount(count)i.setState(&hasItemState{i.goodMachine})returnnil}func(i*noItemState)requestItem()error{returnfmt.Errorf("itemoutofstock")}func(i*noItemState)insertMoney(moneyint)error{returnfmt.Errorf("itemoutofstock")}func(i*noItemState)dispenseItem()error{returnfmt.Errorf("itemoutofstock")}//golang:使用指针接收者实现state接口的所有功能,则隐式表示*noItemState指针类型实现了State接口注意:noItemState定义在结构体中,如果添加了goodMachine,则表示noItemState继承了goodMachine类;指针接收器noItemState实现state接口的所有函数,那么我们说*noItemState实现了state接口hasItemState:有商品packagemainimport"fmt"typehasItemStatestruct{*goodMachine}func(v*hasItemState)addItem(countint)error{v.incrementItemCount(count)returnnil}//有人选择了商品--->缺货状态/已选择产品func(v*hasItemState)requestItem()error{ifv.goodMachine.itemCount==0{v.setState(&noItemState{v.goodMachine})returnfmt.Errorf("noitempresent")}fmt.Print("itemrequested\n"("Pleaseselectitemfirst")}itemRequestedState:有人选择了一个产品packagemainimport"fmt"typeitemRequestedStatestruct{*goodMachine}func(i*itemRequestedState)addItem(countint)error{returnfmt.Errorf("shoppingisinprocess")}func(i*itemRequestedState)requestItem(error{returnfmt.Errorf("itemalreadyrequested")}//支付---->收到状态func(i*itemRequestedquestedState)insertMoney(moneyint)error{ifmoney