狀態(tài)模式

概念

在狀態(tài)模式(State Pattern),當(dāng)一個(gè)對(duì)象的內(nèi)在狀態(tài)改變時(shí)允許改變其行為,這個(gè)對(duì)象看起來(lái)像是改變了其類。

狀態(tài)模式主要解決的是當(dāng)控制一個(gè)對(duì)象狀態(tài)轉(zhuǎn)換的條件表達(dá)式過于復(fù)雜時(shí)的情況,把狀態(tài)的判斷邏輯轉(zhuǎn)移到表示不同狀態(tài)的一系列類當(dāng)中, 可以把復(fù)雜的邏輯簡(jiǎn)化。當(dāng)然, 如果這個(gè)狀態(tài)判斷很簡(jiǎn)單,就沒有必要使用'狀態(tài)模式'了。

UML類圖

statepattern.png

使用場(chǎng)景和優(yōu)缺點(diǎn)

使用場(chǎng)景

代碼中包含大量與對(duì)象狀態(tài)有關(guān)的條件語(yǔ)句, 當(dāng)一個(gè)對(duì)象的行為取決于他的狀態(tài), 并且他必須在運(yùn)行時(shí)刻根據(jù)狀態(tài)改變他的行為時(shí), 既可以考慮使用狀態(tài)模式了。

優(yōu)點(diǎn)

  • 行為和狀態(tài)解耦

將與特定狀態(tài)相關(guān)的行為局部話, 并且將不同的狀態(tài)的行為分割開來(lái)。

  • 易擴(kuò)展

將所有與某個(gè)狀態(tài)有關(guān)的行為放到一個(gè)類中,并且可以方便地增加新的狀態(tài),只需要改變對(duì)象狀態(tài)即可改變對(duì)象的行為

  • 簡(jiǎn)化邏輯
  1. 消除了龐大的條件分支語(yǔ)句, 將某一類狀態(tài)的行為放到同一個(gè)類中。
  2. 可以讓多個(gè)環(huán)境對(duì)象共享一個(gè)狀態(tài)對(duì)象,從而減少系統(tǒng)中對(duì)象的個(gè)數(shù)。

缺點(diǎn)

  • 狀態(tài)模式的使用必然會(huì)增加系統(tǒng)類和對(duì)象的個(gè)數(shù)
  • 狀態(tài)模式的結(jié)構(gòu)與實(shí)現(xiàn)都較為復(fù)雜,如果使用不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂
  • 狀態(tài)模式對(duì)"開閉原則"的支持并不太好,對(duì)于可以切換狀態(tài)的狀態(tài)模式,增加新的狀態(tài)類需要修改那些負(fù)責(zé)狀態(tài)轉(zhuǎn)換的源代碼,否則無(wú)法切換到新增狀態(tài),而且修改某個(gè)狀態(tài)類的行為也需修改對(duì)應(yīng)類的源代碼

代碼實(shí)現(xiàn)


package main

import (
    "fmt"
)

type IState interface {
    WriteProgram(work Work)
}

type Work struct {
    State      IState
    Hour       float64
    TaskFinish bool
}

func (w *Work) SetState(state IState) {
    w.State = state
}
func (w *Work) WriteProgram() {
    w.State.WriteProgram(*w)
}


type ForenoonState struct {
}

func (f *ForenoonState) WriteProgram(work Work) {
    if work.Hour < 12 {
        fmt.Printf("當(dāng)前時(shí)間:%v點(diǎn),上午工作 精神百倍", work.Hour)
    } else {
        work.SetState(&NoonState{})
        work.WriteProgram()
    }
}

type NoonState struct {
}

func (n *NoonState) WriteProgram(work Work) {
    if work.Hour < 13 {
        fmt.Printf("當(dāng)前時(shí)間:%v點(diǎn),餓了 午飯 犯困 午休", work.Hour)
    } else {
        work.SetState(&AfternoonState{})
        work.WriteProgram()
    }
}

type AfternoonState struct {
}

func (a *AfternoonState) WriteProgram(work Work) {
    if work.Hour < 17 {
        fmt.Printf("當(dāng)前時(shí)間:%v點(diǎn),下午狀態(tài)還不錯(cuò) 繼續(xù)努力", work.Hour)
    } else {
        work.SetState(&EveningState{})
        work.WriteProgram()
    }
}

type EveningState struct {
}

func (e *EveningState) WriteProgram(work Work) {
    if work.TaskFinish {
        work.SetState(&RestState{})
        work.WriteProgram()
    } else {
        if work.Hour < 21 {
            fmt.Printf("當(dāng)前時(shí)間:%v點(diǎn),加班哦 疲累至極", work.Hour)
        } else {
            work.SetState(&SleepState{})
            work.WriteProgram()
        }
    }
}

type RestState struct {
}

func (r *RestState) WriteProgram(work Work) {
    fmt.Printf("當(dāng)前時(shí)間:%v點(diǎn),下班回家了", work.Hour)
}

type SleepState struct {
}

func (s *SleepState) WriteProgram(work Work) {
    fmt.Printf("當(dāng)前時(shí)間:%v點(diǎn),不行了 睡著了", work.Hour)
}

func main() {
    //狀態(tài)模式
    emergencyProject := Work{State: &ForenoonState{}}
    emergencyProject.Hour = 9
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 10
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 12
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 13
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 14
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 17

    emergencyProject.TaskFinish = true

    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 19
    emergencyProject.WriteProgram()
    fmt.Println()
    emergencyProject.Hour = 22
    emergencyProject.WriteProgram()
    fmt.Println()
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容