注:本文已发布超过一年,请注意您所使用工具的相关版本是否适用
序
笔记
代码实现
通过下面的例子可以发现,引入状态模式来写状态机会有引入比较多的结构体,并且改动代码的时候如果要新增或者是删除某一个状态的话,修改也需要在其他状态的结构体方法中修改,所以这个不太适合状态经常变更或者是状态很多的情况
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
package state
import "fmt"
type Machine struct { state IState }
func (m *Machine) SetState(state IState) { m.state = state }
func (m *Machine) GetStateName() string { return m.state.GetName() }
func (m *Machine) Approval() { m.state.Approval(m) }
func (m *Machine) Reject() { m.state.Reject(m) }
type IState interface { Approval(m *Machine) Reject(m *Machine) GetName() string }
type leaderApproveState struct{}
func (leaderApproveState) Approval(m *Machine) { fmt.Println("leader 审批成功") m.SetState(GetFinanceApproveState()) }
func (leaderApproveState) GetName() string { return "LeaderApproveState" }
func (leaderApproveState) Reject(m *Machine) {}
func GetLeaderApproveState() IState { return &leaderApproveState{} }
type financeApproveState struct{}
func (f financeApproveState) Approval(m *Machine) { fmt.Println("财务审批成功") fmt.Println("出发打款操作") }
func (f financeApproveState) Reject(m *Machine) { m.SetState(GetLeaderApproveState()) }
func (f financeApproveState) GetName() string { return "FinanceApproveState" }
func GetFinanceApproveState() IState { return &financeApproveState{} }
|
单元测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package state
import ( "testing"
"github.com/stretchr/testify/assert" )
func TestMachine_GetStateName(t *testing.T) { m := &Machine{state: GetLeaderApproveState()} assert.Equal(t, "LeaderApproveState", m.GetStateName()) m.Approval() assert.Equal(t, "FinanceApproveState", m.GetStateName()) m.Reject() assert.Equal(t, "LeaderApproveState", m.GetStateName()) m.Approval() assert.Equal(t, "FinanceApproveState", m.GetStateName()) m.Approval() }
|
关注我获取更新
猜你喜欢