状态机是什么
有限状态机(finite-state machine, FSM)又称有限自动状态机,简称状态机。 有限状态机是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
这看起来和动态规划很像,都包括了状态和转移,一般动态规划是算法,转移的时候考虑最优情况;而状态机则是表示状态变化问题的模型。
百科上的图
- 一个示例状态表
| 当前状态→ 条件↓ | 状态A | 状态B | 状态C |
|---|---|---|---|
| 条件1 | ... | ... | ... |
| 条件2 | ... | 状态C | ... |
| 条件3 | ... | ... | ... |
- 一个示例状态图和对应的代码如下
kotlin代码
// 使用 Kotlin 实现一个电视状态机
class TvStateMachine {
private var state: TvState = OffState()
fun handleEvent(event: TvEvent) {
state = state.handleEvent(event)
}
interface TvState {
fun handleEvent(event: TvEvent): TvState
}
class OffState : TvState {
override fun handleEvent(event: TvEvent): TvState {
return when (event) {
TvEvent.PowerOnEvent -> {
println("Turning TV on...")
OnState()
}
else -> {
println("TV is off, no other events are allowed")
this
}
}
}
}
class OnState : TvState {
private var volume = 20
private var channel = "channel Anime"
override fun handleEvent(event: TvEvent): TvState {
return when (event) {
TvEvent.PowerOffEvent -> {
println("Turning TV off...")
OffState()
}
is TvEvent.VolumeUpEvent -> {
volume = (volume + 10).coerceAtMost(100)
println("Volume increased to $volume")
this
}
is TvEvent.VolumeDownEvent -> {
volume = (volume - 10).coerceAtLeast(0)
println("Volume decreased to $volume")
this
}
is TvEvent.SwitchChannelEvent -> {
channel = event.channelName
println("Switched to channel $channel")
this
}
else -> {
println("Unknown event")
this
}
}
}
}
sealed class TvEvent {
object PowerOnEvent : TvEvent()
object PowerOffEvent : TvEvent()
class VolumeUpEvent(val increment: Int = 10) : TvEvent()
class VolumeDownEvent(val decrement: Int = 10) : TvEvent()
class SwitchChannelEvent(val channelName: String) : TvEvent()
}
}
val tvStateMachine by lazy {
TvStateMachine()
}
fun main() {
// 处理状态机事件
tvStateMachine.handleEvent(TvStateMachine.TvEvent.PowerOnEvent)
tvStateMachine.handleEvent(TvStateMachine.TvEvent.VolumeUpEvent(20))
tvStateMachine.handleEvent(TvStateMachine.TvEvent.SwitchChannelEvent("channel Animal World"))
tvStateMachine.handleEvent(TvStateMachine.TvEvent.VolumeDownEvent(10))
tvStateMachine.handleEvent(TvStateMachine.TvEvent.PowerOffEvent)
}