searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Golang状态机

2023-12-12 01:44:08
13
0

状态机常用于状态流转,尤其是对于复杂业务,通常涉及到复杂的状态流转逻辑

本文实现了一种简单的状态机,并通过友好的方式提供使用接口

 

状态机可以用状态图标识,包含两个元素:

节点:节点即状态的标识,有多少种状态就有多少个节点

连线:根据连线的不同可分为有向连线和无向连线,代表着状态流转的触发条件

 

如下图就是一个简单的状态图

 

import (
	"fmt"
)

const (
	StateStart = "start"
	StateEnd   = "end"
)

type StateMachine struct {
	is             any                         // 初始状态
	fs             any                         // 终止状态
	g              map[any]map[any]map[any]int // 有向图 s1 -> s2 -> trigger
	as             states                      // 所有状态
}

func (s *StateMachine) Permit(from, to any, triggers ...any) *StateMachine {
	if _, ok := s.g[from]; !ok {
		s.g[from] = make(map[any]map[any]int)
	}
	if _, ok := s.g[from][to]; !ok {
		s.g[from][to] = make(map[any]int)
	}
	for _, trigger := range triggers {
		s.g[from][to][trigger] = 1
	}
	if !s.as.contains(from) {
		s.as = append(s.as, from)
	}
	if !s.as.contains(to) {
		s.as = append(s.as, to)
	}
	return s
}

func (s *StateMachine) PathThrough(from, to any, triggers ...any) bool {
	if _, ok := s.g[from]; !ok {
		return false
	}
	if _, ok := s.g[from][to]; !ok {
		return false
	}
	for _, trigger := range triggers {
		if _, ok := s.g[from][to][trigger]; !ok {
			return false
		}
	}
	return true
}

func (s *StateMachine) Next(from any, trigger any) (to any, ok bool) {
	if _, ok = s.g[from]; !ok {
		return nil, false
	}
	for to, m := range s.g[from] {
		if _, ok = m[trigger]; ok {
			return to, true
		}
	}
	return nil, false
}

func New() *StateMachine {
	return &StateMachine{
		is: StateStart,
		fs: StateEnd,
		g:  make(map[any]map[any]map[any]int),
	}
}
0条评论
0 / 1000
李****瑛
5文章数
0粉丝数
李****瑛
5 文章 | 0 粉丝
李****瑛
5文章数
0粉丝数
李****瑛
5 文章 | 0 粉丝
原创

Golang状态机

2023-12-12 01:44:08
13
0

状态机常用于状态流转,尤其是对于复杂业务,通常涉及到复杂的状态流转逻辑

本文实现了一种简单的状态机,并通过友好的方式提供使用接口

 

状态机可以用状态图标识,包含两个元素:

节点:节点即状态的标识,有多少种状态就有多少个节点

连线:根据连线的不同可分为有向连线和无向连线,代表着状态流转的触发条件

 

如下图就是一个简单的状态图

 

import (
	"fmt"
)

const (
	StateStart = "start"
	StateEnd   = "end"
)

type StateMachine struct {
	is             any                         // 初始状态
	fs             any                         // 终止状态
	g              map[any]map[any]map[any]int // 有向图 s1 -> s2 -> trigger
	as             states                      // 所有状态
}

func (s *StateMachine) Permit(from, to any, triggers ...any) *StateMachine {
	if _, ok := s.g[from]; !ok {
		s.g[from] = make(map[any]map[any]int)
	}
	if _, ok := s.g[from][to]; !ok {
		s.g[from][to] = make(map[any]int)
	}
	for _, trigger := range triggers {
		s.g[from][to][trigger] = 1
	}
	if !s.as.contains(from) {
		s.as = append(s.as, from)
	}
	if !s.as.contains(to) {
		s.as = append(s.as, to)
	}
	return s
}

func (s *StateMachine) PathThrough(from, to any, triggers ...any) bool {
	if _, ok := s.g[from]; !ok {
		return false
	}
	if _, ok := s.g[from][to]; !ok {
		return false
	}
	for _, trigger := range triggers {
		if _, ok := s.g[from][to][trigger]; !ok {
			return false
		}
	}
	return true
}

func (s *StateMachine) Next(from any, trigger any) (to any, ok bool) {
	if _, ok = s.g[from]; !ok {
		return nil, false
	}
	for to, m := range s.g[from] {
		if _, ok = m[trigger]; ok {
			return to, true
		}
	}
	return nil, false
}

func New() *StateMachine {
	return &StateMachine{
		is: StateStart,
		fs: StateEnd,
		g:  make(map[any]map[any]map[any]int),
	}
}
文章来自个人专栏
Golang语言
3 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0