欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

概念示例

讓我們?cè)谝慌_(tái)自動(dòng)售貨機(jī)上使用狀態(tài)設(shè)計(jì)模式。 為簡(jiǎn)單起見(jiàn), 讓我們假設(shè)自動(dòng)售貨機(jī)僅會(huì)銷(xiāo)售一種類(lèi)型的商品。 同時(shí), 依然為了簡(jiǎn)單起見(jiàn), 我們假設(shè)自動(dòng)售貨機(jī)可處于 4 種不同的狀態(tài)中:

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

同時(shí), 自動(dòng)售貨機(jī)也會(huì)有不同的操作。 再一次的, 為了簡(jiǎn)單起見(jiàn), 我們假設(shè)其只會(huì)執(zhí)行 4 種操作:

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

當(dāng)對(duì)象可以處于許多不同的狀態(tài)中時(shí)應(yīng)使用狀態(tài)設(shè)計(jì)模式, 同時(shí)根據(jù)傳入請(qǐng)求的不同, 對(duì)象需要變更其當(dāng)前狀態(tài)。

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

根據(jù)其當(dāng)前狀態(tài), 機(jī)器可就相同請(qǐng)求采取不同的行為。 例如, 如果用戶(hù)想要購(gòu)買(mǎi)一件商品, 機(jī)器將在 有商品狀態(tài)時(shí)繼續(xù)操作, 而在 無(wú)商品狀態(tài)時(shí)拒絕操作。

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

vendingMachine.go: 背景

package main
import "fmt"
type VendingMachine struct {
	hasItem       State
	itemRequested State
	hasMoney      State
	noItem        State
	currentState State // 當(dāng)前狀態(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"
// 無(wú)貨狀態(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: 客戶(hù)端代碼

package main
import (
	"fmt"
	"log"
)
func main() {
	vendingMachine := newVendingMachine(1, 10)
	// 獲取一個(gè)商品
	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設(shè)計(jì)模式之狀態(tài)模式講解和代碼示例的文章就介紹到這了,更多相關(guān)Go狀態(tài)模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

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

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

    Golang中Options模式的使用

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

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

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

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

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

    GO語(yǔ)言創(chuàng)建錢(qián)包并遍歷錢(qián)包(wallet)的實(shí)現(xiàn)代碼

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

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

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

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

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

    詳解Golang中日志庫(kù)glog的使用

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

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

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

最新評(píng)論