成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我是狀態機, 一顆永遠騷動的機器引擎

開發 前端
狀態機是一種行為設計模式,它允許對象在其內部狀態改變時改變其行為。看起來好像對象改變了它的類。

[[417324]]

本文轉載自微信公眾號「精益碼農」,作者小碼甲 。轉載本文請聯系精益碼農公眾號。

狀態機是一種行為設計模式,它允許對象在其內部狀態改變時改變其行為。看起來好像對象改變了它的類。

請仔細理解上面每一個字。

我們以自動售貨機為例,為簡化演示,我們假設自動售貨機只有1種商品, 故自動售貨機有itemCount 、itemPrice 2個屬性。

不考慮動作的前后相關性,自動售貨機對外暴露4種行為:

  • 給自動售貨機加貨 addItem
  • 選擇商品 requestItem
  • 付錢 insertMoney
  • 出貨 dispenseItem

重點來了,當發生某種行為,自動售貨機會進入如下4種狀態之一, 并據此狀態做出特定動作, 之后進入另外一種狀態.....

  • 有商品 hasItem
  • 無商品 noItem
  • 已經選好商品 itemRequested
  • 已付錢 hasMoney

當對象可能處于多種不同的狀態之一、根據傳入的動作更改當前的狀態, 繼續接受后續動作,狀態再次發生變化.....

這樣的模式類比于機器引擎,周而復始的工作和狀態轉化,這也是狀態機的定語叫“機Machine”的原因。

有了以上思路,我們嘗試溝通UML 偽代碼:

狀態機設計模式的偽代碼實現:

  • 所謂的機器Machine維護了狀態切換的上下文
  • 機器對外暴露的行為,驅動機器的狀態變更, 行為和狀態是有因果關系的
  • 機器到達特定的狀態 只具備特定的行為,其他行為是不被允許的, 這在外面看,貌似是對象改變了原類的行為

下面使用golang實現了 狀態機設計模型:這里你也可以看下golang 是如何體現OOP中的類繼承、接口實現

goodMachine:狀態變更上下文

  1. package main 
  2.  
  3. import ( 
  4.  "fmt" 
  5.  "reflect" 
  6.  
  7. type goodMachine struct { 
  8.  currentState state 
  9.  itemCount    int 
  10.  itemPrice    int 
  11.  
  12. func newGoodMachine(itemCount, itemPrice int) *goodMachine { 
  13.  v := &goodMachine{ 
  14.   itemCount: itemCount, 
  15.   itemPrice: itemPrice, 
  16.  } 
  17.  if itemCount <= 0 { 
  18.   v.setState(&noItemState{v}) // 實現state接口的是*noItemState 指針類型 
  19.  } else { 
  20.   v.setState(&hasItemState{v}) 
  21.  } 
  22.  return v 
  23.  
  24. func (v *goodMachine) setState(s state) { 
  25.  fmt.Println("enter state: ", reflect.TypeOf(s)) 
  26.  v.currentState = s 
  27.  
  28. func (v *goodMachine) requestItem() error { 
  29.  return v.currentState.requestItem() 
  30.  
  31. func (v *goodMachine) addItem(count int) error { 
  32.  return v.currentState.addItem(count
  33.  
  34. func (v *goodMachine) insertMoney(money int) error { 
  35.  return v.currentState.insertMoney(money) 
  36.  
  37. func (v *goodMachine) incrementItemCount(count int) { 
  38.  v.itemCount += count 
  39.  
  40. func (v goodMachine) dispenseItem() error { 
  41.  return v.currentState.dispenseItem() 

自動售貨機對外的行為,被委托給特定的state對象

state:自動售貨機對外暴露的行為

  1. package main 
  2.  
  3. //  代表某種狀態,能接受的某種動作 
  4. type state interface { 
  5.  addItem(count int) error 
  6.  requestItem() error 
  7.  insertMoney(money int) error 
  8.  dispenseItem() error 

noItemState : 無商品

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type noItemState struct { 
  6.  *goodMachine // 存在匿名類型 goodMachine,類型是*goodMachine 
  7.  
  8. //  給自動售貨機供貨-----> 有貨狀態 
  9. func (i *noItemState) addItem(count int) error { 
  10.  i.incrementItemCount(count
  11.  i.setState(&hasItemState{i.goodMachine}) 
  12.  return nil 
  13.  
  14. func (i *noItemState) requestItem() error { 
  15.  return fmt.Errorf("item out of  stock"
  16.  
  17. func (i *noItemState) insertMoney(money int) error { 
  18.  return fmt.Errorf("item out of stock"
  19.  
  20. func (i *noItemState) dispenseItem() error { 
  21.  return fmt.Errorf("item out of stock"
  22.  
  23. // golang: 使用指針接受者實現了state接口的全部函數,那么隱式表明*noItemState 指針類型實現了State接口 

注意:noItemState 結構體內定義了 goodMachine, 就表明noItemState繼承了goodMachine類 ;

指針接受者 noItemState實現了state接口的所有函數,那么我們就說*noItemState實現了state接口。

hasItemState: 有商品

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type hasItemState struct { 
  6.  *goodMachine 
  7.  
  8. func (v *hasItemState) addItem(count int) error { 
  9.  v.incrementItemCount(count
  10.  return nil 
  11.  
  12. // 有人選擇了商品---> 沒貨狀態/已經選定商品 
  13. func (v *hasItemState) requestItem() error { 
  14.  if v.goodMachine.itemCount == 0 { 
  15.   v.setState(&noItemState{v.goodMachine}) 
  16.   return fmt.Errorf("no item present"
  17.  } 
  18.  
  19.  fmt.Print("item  requested\n"
  20.  v.setState(&itemRequestedState{v.goodMachine}) 
  21.  return nil 
  22.  
  23. func (v *hasItemState) insertMoney(money int) error { 
  24.  return fmt.Errorf("Please select item first"
  25.  
  26. func (v *hasItemState) dispenseItem() error { 
  27.  return fmt.Errorf("Please select item first"

itemRequestedState:有人選定商品

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type itemRequestedState struct { 
  6.  *goodMachine 
  7.  
  8. func (i *itemRequestedState) addItem(count int) error { 
  9.  return fmt.Errorf("shopping is  in  process"
  10.  
  11. func (i *itemRequestedState) requestItem() error { 
  12.  return fmt.Errorf("item already requested"
  13.  
  14. // 付錢----> 已收錢狀態 
  15. func (i *itemRequestedState) insertMoney(money int) error { 
  16.  if money < i.goodMachine.itemPrice { 
  17.   fmt.Errorf("insert money is less, please insert %d", i.goodMachine) 
  18.  } 
  19.  fmt.Println("money entered is ok"
  20.  i.setState(&hasMoneyState{i.goodMachine}) 
  21.  return nil 
  22. func (i *itemRequestedState) dispenseItem() error { 
  23.  return fmt.Errorf("please insert money first"

hasMoneyState:已付錢

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type hasMoneyState struct { 
  6.  *goodMachine 
  7.  
  8. func (i *hasMoneyState) addItem(count int) error { 
  9.  return fmt.Errorf("shopping is in process"
  10. func (i *hasMoneyState) requestItem() error { 
  11.  return fmt.Errorf("shopping is in process"
  12. func (i *hasMoneyState) insertMoney(money int) error { 
  13.  return fmt.Errorf("already pay money"
  14. func (i *hasMoneyState) dispenseItem() error { 
  15.  fmt.Println("dispensing item"
  16.  i.goodMachine.itemCount = i.goodMachine.itemCount - 1 
  17.  if i.goodMachine.itemCount == 0 { 
  18.   i.setState(&noItemState{i.goodMachine}) 
  19.  } else { 
  20.   i.setState(&hasItemState{i.goodMachine}) 
  21.  } 
  22.  return nil 

main.go 執行

  1. package main 
  2.  
  3. import ( 
  4.   "fmt" 
  5.   "log" 
  6.  
  7. func main() { 
  8.   goodMachine := newGoodMachine(1, 10) 
  9.   err := goodMachine.requestItem() 
  10.   if err != nil { 
  11.     log.Fatalf(err.Error()) 
  12.   } 
  13.  
  14.   err = goodMachine.insertMoney(10) 
  15.   if err != nil { 
  16.     log.Fatalf(err.Error()) 
  17.   } 
  18.  
  19.   err = goodMachine.dispenseItem() 
  20.   if err != nil { 
  21.     log.Fatalf(err.Error()) 
  22.   } 
  23.   fmt.Println() 
  24.  
  25.   err = goodMachine.requestItem() 
  26.   if err != nil { 
  27.     log.Fatalf(err.Error()) 
  28.   } 
  29.   err = goodMachine.insertMoney(10) 
  30.   if err != nil { 
  31.     log.Fatal(err.Error()) 
  32.   } 
  33.   err = goodMachine.dispenseItem() 
  34.   if err != nil { 
  35.     log.Fatalf(err.Error()) 
  36.   } 

初始化了商品數量為1,價格為10 的自動售貨機,連續掏10元錢買兩次, 隨時打印狀態, 輸出如下:

  1. enter state:  *main.hasItemState 
  2. item  requested 
  3. enter state:  *main.itemRequestedState 
  4. money entered is ok 
  5. enter state:  *main.hasMoneyState      
  6. dispensing item 
  7. enter state:  *main.noItemState        
  8.  
  9. 2021/08/11 17:39:45 item out of  stock 
  10. exit status 1 

狀態機為什么定語是機器?Machine?

狀態機表現了:

對象的狀態受外界行為所影響,不斷的切換,到達特定的狀態又只能接受特定的行為, 真實生動的體現了機器Machine引擎的特征。

本文示例亦是學習golang OOP編程的范例,golang 類繼承、接口實現實在是太秀了。 

github: https://github.com/zaozaoniao/statemachine

 

責任編輯:武曉燕 來源: 精益碼農
相關推薦

2020-06-30 15:38:17

戴爾

2022-12-27 14:29:37

javascript動畫

2009-06-10 18:15:36

電腦下鄉家電下鄉

2023-03-06 07:35:30

狀態機工具訂單狀態

2013-09-29 11:08:10

Bay Trail平板電腦

2014-07-30 16:19:13

敏捷華為

2013-04-16 13:57:36

2021-03-15 14:17:38

射頻芯片5G手機信號

2010-07-30 15:58:18

2010-06-18 12:38:38

UML狀態機視圖

2023-03-14 13:57:22

狀態機聊天機器人

2020-10-15 10:38:35

C語言狀態模型

2021-07-08 09:15:20

單片機編程狀態機編程語言

2020-03-27 10:50:29

DSL 狀態機工具

2022-11-01 12:30:11

機器學習解碼系統

2013-09-03 09:57:43

JavaScript有限狀態機

2010-06-18 13:25:44

UML狀態機視圖

2017-02-23 10:50:32

Python微博數據

2017-02-24 19:32:39

微博數據Python

2022-08-26 12:13:40

黑客網絡攻擊
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品无码专区在线观看 | 黄色av网站在线免费观看 | 亚洲精品9999| 国产精品国产三级国产aⅴ原创 | 中文字幕av在线 | av在线三级 | 国产第一页在线观看 | 久草.com | 天天干天天爽 | 亚洲国产精品一区二区三区 | 成人国内精品久久久久一区 | 久久久久一区二区 | 成人影院免费视频 | 久久久久久久久久久久一区二区 | 99久久精品免费看国产四区 | 999免费观看视频 | 久久小视频 | 中文字幕二区 | 日本视频免费 | 中文字幕在线不卡 | 亚洲www啪成人一区二区麻豆 | 手机看片在线播放 | 午夜精品久久久久久不卡欧美一级 | 亚洲第一av | 极品的亚洲| 天天拍天天操 | 欧美日韩国产一区二区三区 | 黄色亚洲网站 | 深夜福利亚洲 | 精品久久久久久 | 欧美日韩不卡合集视频 | 久久久久久久久久爱 | 久草在线 | 亚洲国产欧美一区二区三区久久 | 久久99国产精一区二区三区 | 久久99精品久久久久久国产越南 | 久久久久久亚洲 | 国产精品久久久久久亚洲调教 | 亚洲精品中文在线观看 | 夜夜av| 精品免费观看 |