亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go設計模式之狀態(tài)模式講解和代碼示例

 更新時間:2023年08月11日 08:27:09   作者:demo007x  
狀態(tài)是一種行為設計模式,?讓你能在一個對象的內(nèi)部狀態(tài)變化時改變其行為,該模式將與狀態(tài)相關(guān)的行為抽取到獨立的狀態(tài)類中,?讓原對象將工作委派給這些類的實例,?而不是自行進行處理,本文將通過代碼示例給大家簡單的介紹一下Go狀態(tài)模式

Go 狀態(tài)模式講解和代碼示例

概念示例

讓我們在一臺自動售貨機上使用狀態(tài)設計模式。 為簡單起見, 讓我們假設自動售貨機僅會銷售一種類型的商品。 同時, 依然為了簡單起見, 我們假設自動售貨機可處于 4 種不同的狀態(tài)中:

  • 有商品 (has­Item)
  • 無商品 (no­Item)
  • 商品已請求 (item­Requested)
  • 收到紙幣 (has­Money)

同時, 自動售貨機也會有不同的操作。 再一次的, 為了簡單起見, 我們假設其只會執(zhí)行 4 種操作:

  • 選擇商品
  • 添加商品
  • 插入紙幣
  • 提供商品

當對象可以處于許多不同的狀態(tài)中時應使用狀態(tài)設計模式, 同時根據(jù)傳入請求的不同, 對象需要變更其當前狀態(tài)。

在我們的例子中, 自動售貨機可以有多種不同的狀態(tài), 同時會在這些狀態(tài)之間持續(xù)不斷地互相轉(zhuǎn)換。 我們假設自動售貨機處于 商品已請求狀態(tài)中。 在 “插入紙幣” 的操作發(fā)生后, 機器將自動轉(zhuǎn)換至 收到紙幣狀態(tài)。

根據(jù)其當前狀態(tài), 機器可就相同請求采取不同的行為。 例如, 如果用戶想要購買一件商品, 機器將在 有商品狀態(tài)時繼續(xù)操作, 而在 無商品狀態(tài)時拒絕操作。

自動售貨機的代碼不會被這一邏輯污染; 所有依賴于狀態(tài)的代碼都存在于各自的狀態(tài)實現(xiàn)中。

vendingMachine.go: 背景

package main
import "fmt"
type VendingMachine struct {
	hasItem       State
	itemRequested State
	hasMoney      State
	noItem        State
	currentState State // 當前狀態(tài)
	itemCount    int
	itemPrice    int
}
func newVendingMachine(itemCount, itemPrice int) *VendingMachine {
	v := &VendingMachine{
		itemCount: itemCount,
		itemPrice: itemPrice,
	}
	hasItemState := &HasItemState{vendingMachine: v}
	itemRequestState := &ItemRequestedState{vendingMachine: v}
	hasMoneyState := &HasMoneyState{vendingMachine: v}
	noItemState := &NoItemState{vendingMachine: v}
	v.setState(hasItemState)
	v.hasItem = hasItemState
	v.itemRequested = itemRequestState
	v.hasMoney = hasMoneyState
	v.noItem = noItemState
	return v
}
func (v *VendingMachine) requestItem() error {
	return v.currentState.requestItem()
}
func (v *VendingMachine) addItem(count int) error {
	return v.currentState.addItem(count)
}
func (v *VendingMachine) insertMoney(money int) error {
	return v.currentState.insertMoney(money)
}
func (v *VendingMachine) dispenseItem() error {
	return v.currentState.dispenseItem()
}
func (v *VendingMachine) setState(s State) {
	v.currentState = s
}
func (v *VendingMachine) incrementItemCount(count int) {
	fmt.Printf("Adding %d items \n", count)
	v.itemCount = count + v.itemCount
}

state.go: 狀態(tài)接口

package main
type State interface {
	addItem(int) error
	requestItem() error
	insertMoney(money int) error
	dispenseItem() error
}

noItemState.go: 具體狀態(tài)

package main
import "fmt"
// 無貨狀態(tài)
type NoItemState struct {
	vendingMachine *VendingMachine
}
func (i *NoItemState) requestItem() error {
	return fmt.Errorf("Item out of stock")
}
func (i *NoItemState) addItem(count int) error {
	i.vendingMachine.incrementItemCount(count)
	i.vendingMachine.setState(i.vendingMachine.hasItem)
	return nil
}
func (i *NoItemState) insertMoney(money int) error {
	return fmt.Errorf("Item out of stock")
}
func (i *NoItemState) dispenseItem() error {
	return fmt.Errorf("Item out of stock")
}

hasItemState.go: 具體狀態(tài)

package main
import "fmt"
type HasItemState struct {
	vendingMachine *VendingMachine
}
func (i *HasItemState) requestItem() error {
	if i.vendingMachine.itemCount == 0 {
		i.vendingMachine.setState(i.vendingMachine.noItem)
		return fmt.Errorf("No item present")
	}
	fmt.Printf("Item requested \n")
	i.vendingMachine.setState(i.vendingMachine.itemRequested)
	return nil
}
func (i *HasItemState) addItem(count int) error {
	fmt.Printf("%d item added", count)
	i.vendingMachine.incrementItemCount(count)
	return nil
}
func (i *HasItemState) insertMoney(money int) error {
	return fmt.Errorf("please select item first")
}
func (i *HasItemState) dispenseItem() error {
	return fmt.Errorf("Please select item first")
}

itemRequestedState.go: 具體狀態(tài)

package main
import "fmt"
type ItemRequestedState struct {
	vendingMachine *VendingMachine
}
func (i *ItemRequestedState) requestItem() error {
	return fmt.Errorf("Item already requested")
}
func (i *ItemRequestedState) addItem(count int) error {
	return fmt.Errorf("Item Dispense in progress")
}
func (i *ItemRequestedState) insertMoney(money int) error {
	if money < i.vendingMachine.itemPrice {
		return fmt.Errorf("Inserted money is less. Please insert %d", i.vendingMachine.itemPrice)
	}
	fmt.Println("Money entered is ok")
	i.vendingMachine.setState(i.vendingMachine.hasMoney)
	return nil
}
func (i *ItemRequestedState) dispenseItem() error {
	return fmt.Errorf("Please insert money first")
}

hasMoneyState.go: 具體狀態(tài)

package main
import "fmt"
type HasMoneyState struct {
	vendingMachine *VendingMachine
}
func (i *HasMoneyState) requestItem() error {
	return fmt.Errorf("Item dispense in progress")
}
func (i *HasMoneyState) addItem(count int) error {
	return fmt.Errorf("Item dispense in progress")
}
func (i *HasMoneyState) insertMoney(money int) error {
	return fmt.Errorf("item out of stock")
}
func (i *HasMoneyState) dispenseItem() error {
	fmt.Println("Dispensing Item")
	i.vendingMachine.itemCount = i.vendingMachine.itemCount - 1
	if i.vendingMachine.itemCount == 0 {
		i.vendingMachine.setState(i.vendingMachine.noItem)
	} else {
		i.vendingMachine.setState(i.vendingMachine.hasItem)
	}
	return nil
}

main.go: 客戶端代碼

package main
import (
	"fmt"
	"log"
)
func main() {
	vendingMachine := newVendingMachine(1, 10)
	// 獲取一個商品
	if err := vendingMachine.requestItem(); err != nil {
		log.Fatalf(err.Error())
	}
	if err := vendingMachine.insertMoney(10); err != nil {
		log.Fatal(err.Error())
	}
	if err := vendingMachine.dispenseItem(); err != nil {
		log.Fatal(err.Error())
	}
	fmt.Println("================")
	if err := vendingMachine.addItem(2); err != nil {
		log.Fatal(err.Error())
	}
	fmt.Println()
	if err := vendingMachine.requestItem(); err != nil {
		log.Fatal(err.Error())
	}
	if err := vendingMachine.insertMoney(10); err != nil {
		log.Fatal(err.Error())
	}
	if err := vendingMachine.dispenseItem(); err != nil {
		log.Fatal(err.Error())
	}
}

output.txt: 執(zhí)行結(jié)果

Item requested 
Money entered is ok
Dispensing Item
================
Adding 2 items 

Item requested 
Money entered is ok
Dispensing Item

到此這篇關(guān)于Go設計模式之狀態(tài)模式講解和代碼示例的文章就介紹到這了,更多相關(guān)Go狀態(tài)模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang利用casbin實現(xiàn)權(quán)限驗證詳解

    Golang利用casbin實現(xiàn)權(quán)限驗證詳解

    Casbin是一個強大的、高效的開源訪問控制框架,其權(quán)限管理機制支持多種訪問控制模型,Casbin只負責訪問控制。本文將利用casbin實現(xiàn)權(quán)限驗證功能,需要的可以參考一下
    2023-02-02
  • 淺談go中切片比數(shù)組好用在哪

    淺談go中切片比數(shù)組好用在哪

    數(shù)組和切片都是常見的數(shù)據(jù)結(jié)構(gòu),本文將介紹Go語言中數(shù)組和切片的基本概念,同時詳細探討切片的優(yōu)勢,感興趣的可以了解下
    2023-06-06
  • Golang中Options模式的使用

    Golang中Options模式的使用

    選項模式是一種設計模式,允許通過提供選項自定義行為,Golang中的應用廣泛,尤其是庫和框架設計中,本文深入探討Golang中選項模式的實現(xiàn),包括函數(shù)選項和結(jié)構(gòu)體選項兩種方式,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-11-11
  • Go項目實現(xiàn)優(yōu)雅關(guān)機與平滑重啟功能

    Go項目實現(xiàn)優(yōu)雅關(guān)機與平滑重啟功能

    無論是優(yōu)雅關(guān)機還是優(yōu)雅重啟歸根結(jié)底都是通過監(jiān)聽特定系統(tǒng)信號,然后執(zhí)行一定的邏輯處理保障當前系統(tǒng)正在處理的請求被正常處理后再關(guān)閉當前進程,這篇文章主要介紹了Go實現(xiàn)優(yōu)雅關(guān)機與平滑重啟 ,需要的朋友可以參考下
    2022-10-10
  • Golang如何使用go.mod配置加載本地模塊

    Golang如何使用go.mod配置加載本地模塊

    這篇文章主要介紹了Golang如何使用go.mod配置加載本地模塊問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • GO語言創(chuàng)建錢包并遍歷錢包(wallet)的實現(xiàn)代碼

    GO語言創(chuàng)建錢包并遍歷錢包(wallet)的實現(xiàn)代碼

    比特幣錢包實際上是一個密鑰對,當你安裝 一個錢包應用,或者是使用一個比特幣客戶端來生成一個新地址是,他就會為你生成一個密鑰對,今天通過本文給大家分享go語言遍歷錢包的相關(guān)知識,一起看看吧
    2021-05-05
  • Go實現(xiàn)用戶每日限額的方法(例一天只能領(lǐng)三次福利)

    Go實現(xiàn)用戶每日限額的方法(例一天只能領(lǐng)三次福利)

    這篇文章主要介紹了Go實現(xiàn)用戶每日限額的方法(例一天只能領(lǐng)三次福利)
    2022-01-01
  • Golang并發(fā)利器sync.Once的用法詳解

    Golang并發(fā)利器sync.Once的用法詳解

    在某些場景下,我們需要初始化一些資源。有時會采用延遲初始化的方式,在真正需要資源的時候才進行初始化。在這種情況下,Go語言中的sync.Once提供一個優(yōu)雅且并發(fā)安全的解決方案,本文將對其進行詳細介紹
    2023-04-04
  • 詳解Golang中日志庫glog的使用

    詳解Golang中日志庫glog的使用

    golang/glog?是?C++?版本?google/glog?的?Go?版本實現(xiàn),基本實現(xiàn)了原生?glog?的日志格式,下面大家就跟隨小編一起了解一下glog的具體使用吧
    2023-09-09
  • Go實現(xiàn)替換(覆蓋)文件某一行內(nèi)容的示例代碼

    Go實現(xiàn)替換(覆蓋)文件某一行內(nèi)容的示例代碼

    本文主要介紹了Go實現(xiàn)替換(覆蓋)文件某一行內(nèi)容的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07

最新評論