|
楼主 |
发表于 2021-11-17 17:31:50
|
显示全部楼层
本帖最后由 jarlyyn 于 2021-11-17 05:39 PM 编辑
接下来,我们通过购买商品来看下,状态驱动的机器是怎么写的。
购买商品的流程大体如下
那么,我们需要的是
这几个额外状态
首先是全局的入口函数
- (function(app){
- app.Produce=function(id){
- let item=App.API.GetItem(id)
- if (item==null){
- throw "item "+id +" not found"
- }
- let a=app.Automaton.Push("core.state.produce.check")
- a.WithTransitions([item.Type])
- a.WithData("Item",item)
- app.ChangeState("ready")
- }
- })(App)
复制代码 很家单,获取注册过的道具信息,将item.Type作为初始状态,将item作为Item上下文,,将检查物品作为终点,进入ready开始运行
然后是购买的初始状态 goods
- (function (app) {
- let basicstate = Include("core/state/basicstate.js")
- let StateGoods=function(){
- basicstate.call(this)
- this.ID="goods"
- }
- StateGoods.prototype = Object.create(basicstate.prototype)
- StateGoods.prototype.Enter=function(context,oldstatue){
- basicstate.prototype.Enter.call(this,context,oldstatue)
- let item=app.GetContext("Item")
- let a=app.Automaton.Push()
- a.WithTransitions(["core.state.produce.move","nobusy","core.state.produce.execute","nobusy"])
- a.WithData("Item",item)
- app.ChangeState("ready")
- }
- return StateGoods
- })(App)
复制代码
很明显,定义里系列的过渡,["core.state.produce.move","nobusy","core.state.produce.execute","nobusy"],和上述的图一致。
状态core.state.produce.move代码
- (function (app) {
- let basicstate = Include("core/state/basicstate.js")
- let StateProduceMove=function(){
- basicstate.call(this)
- this.ID="core.state.produce.move"
- }
- StateProduceMove.prototype = Object.create(basicstate.prototype)
- StateProduceMove.prototype.Enter=function(context,oldstatue){
- basicstate.prototype.Enter.call(this,context,oldstatue)
- let item=app.GetContext("Item")
- app.NewMove("walk",item.Location).Start()
- }
- return StateProduceMove
- })(App)
复制代码
很简单的直接Start一个move并Start,完全不管下一个状态是什么
nobusy状态
- (function (app) {
- let basicstate = Include("core/state/basicstate.js")
- let StateNoBusy=function(){
- basicstate.call(this)
- this.ID="nobusy"
- this.Callback=""
- }
- StateNoBusy.prototype = Object.create(basicstate.prototype)
- StateNoBusy.prototype.Enter=function(context,oldstatue){
- basicstate.prototype.Enter.call(this,context,oldstatue)
- app.CheckBusy(this.Callback)
- }
- return StateNoBusy
- })(App)
复制代码 这是一个通用模块,检查忙,不忙进入ready状态
core.state.produce.execute状态
- (function (app) {
- let basicstate = Include("core/state/basicstate.js")
- let StateProduceExecute=function(){
- basicstate.call(this)
- this.ID="core.state.produce.execute"
- }
- StateProduceExecute.prototype = Object.create(basicstate.prototype)
- StateProduceExecute.prototype.Enter=function(context,oldstatue){
- basicstate.prototype.Enter.call(this,context,oldstatue)
- let item=app.GetContext("Item")
- app.Send(item.Command)
- app.ChangeState("ready")
- }
- return StateProduceExecute
- })(App)
复制代码 发送上下文变量Item里的Command,因为是使用上下文变量,所以不会和全局冲突。同样不检测下一步是什么。
如果需要做重试处理,也应该放在这里
core.state.produce.check状态:
- (function (app) {
- let basicstate = Include("core/state/basicstate.js")
- let StateProduceExecute=function(){
- basicstate.call(this)
- this.ID="core.state.produce.check"
- }
- StateProduceExecute.prototype = Object.create(basicstate.prototype)
- StateProduceExecute.prototype.Enter=function(context,oldstatue){
- basicstate.prototype.Enter.call(this,context,oldstatue)
- app.Send("i2")
- app.ResponseReady()
- }
- return StateProduceExecute
- })(App)
复制代码
发个i2触发更新道具信息,然后发送一个Response等服务器响应后进入Ready状态
虽然整个购物不复杂,但很明显的体现了状态模式写代码的流程
分阶段,画图,分别写触发,维护上下文变量,代码互相解耦。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|