本文转载请联系神光编程秘籍公众号。不知道大家有没有遇到过代码逻辑特别复杂的情况,需要大量的ifelse判断,每种情况都有自己的逻辑。这么多这样的ifelse之后,读代码继续迭代就变得很吃力了。如果遇到这种代码,该如何优化呢?本文提供了一种思路,通过状态机来简化复杂的ifelse代码逻辑。看完这篇文章,你会知道:什么是状态机什么是状态自动机Typescript源码如何使用状态机让流程更清晰词法分析中的状态机如何在业务代码中使用状态机状态机是做什么用的processing的情况有很多种,我们把每种情况的处理逻辑封装成一个状态,然后不同情况之间的转换就变成了状态转换。这个代码组织就是状态机。当每一个状态都知道输入某段内容时要进入哪个状态,状态的流动和不同状态的处理就自动循环进行。这称为状态自动机(automation)。如果一个状态只有A个后续状态,则称为确定性有限状态自动机(DFA)。状态之间的流动可以用状态转换图来表示。typescript源码中的状态机typescript编译器通过状态机来组织整个编译过程:首先tsc划分了很多状态,每个状态处理一个逻辑。例如:CreateProgram将源代码解析成astSyntaxDiagnostics处理语法错误SemanticDiagnostics处理语义错误Emit生成目标代码Typescript通过修改这个状态来完成不同处理逻辑的流程,如果处理到结束状态,则表示流程结束.这样,整个流程可以很容易地扩展和修改。例如,如果要扩展一个stage,只需要添加一个state,如果要修改某个state的处理逻辑,只需要修改statemachine的state的方向即可。而不是大量的ifelse混在一起,很难扩展和修改。可以看出,状态机让typescript的编译步骤可以灵活扩展和修改。词法分析中的状态机其实状态机最常用的地方就是词法分析,因为每个token都是一个处理情况,自然会有很多ifelse。也可以像下面这样用ifelse做分词。这是wenyan的词法分析逻辑,但是代码很难维护。更好的做法是使用状态机(DFA)进行分词,将每个token的处理过程封装成一个状态。状态流是通过对边界条件的判断来进行的。例如,一个wxml解析器划分了这些状态:每个状态在一种情况下处理一个token的标识:处理逻辑的流程是由状态的变化驱动的:这是在状态之间不断进行的流程,当结束时字符串处理完毕,所有分词完成。业务代码中的状态机业务代码在遇到各种ifelse判断的时候也可以使用状态机进行优化。将每一种情况封装成一个状态,通过某种条件触发状态的流动,然后在状态机中选择不同的状态处理逻辑进行处理。无论是游戏中不同状态的不同处理逻辑,还是ui项目中不同状态的不同渲染,当代码逻辑复杂的时候,难免会有很多ifelse。这时候就可以用状态机的思想来优化一下。这样,后续扩展处理逻辑和修改不同条件下的处理逻辑就变得简单明了。总结我们首先明确了状态机的概念:通过不同的状态来封装不同情况的处理逻辑,通过状态修改来完成处理逻辑之间的流程。如果每个状态都知道下一个状态是什么,那么在一个周期内自动完成状态流的状态机就是状态自动机。当状态有限时,它是一个有限状态自动机(DFA)。typescript编译器是通过状态自动机进行处理的,状态自动机封装了很多状态,每个状态都知道下一个状态是什么,直到处理到终止状态,编译结束。有限状态自动机(DFA)通常用于词法分析。不同的token处理不同的状态,通过不同的输入字符传递状态。字符串处理完成后,分词就完成了。在业务代码中,往往会出现不同的情况,不同的处理方式。这些情况会在一定条件下进行转换,比如开始、暂停、结束、重启。这种代码很适合用状态机来优化,不然会出现很多ifelse。总之,当逻辑可以分为不同的情况,并且各种情况可以相互转换时,可以使用状态机进行优化,可以省去很多ifelse,代码可读性好,可扩展性强,和可维护的。性会有很大的改善。希望这篇文章能让你了解什么是状态机,什么时候可以使用状态机,状态机能带来哪些改进,并真正在你的代码中使用它。
