你第一次听说状态机时,你认为它是什么?我以为它是一个调试器。我可以用它来寻找我代码中那些恼人的错误。状态机不是一个调试器。然而,当你掌握了如何使用状态机时,你所写的代码就会变得没有错误。
什么是状态机?
状态机是一个抽象的概念,它定义和规划了一个应用程序的阶段和转换。应用程序只在事件发生时进行转换。例如,一个状态机表示一个应用程序的初始状态,以及如果用户使用该应用程序,下一个阶段--过渡--会是什么。

例如,在一台正常运行的自动取款机(ATM)中,你可以插入你的卡,它的屏幕上会显示类似欢迎的信息。这就是为ATM编程的程序员如何设计机器的初始状态。一旦你插入你的卡,自动取款机就会改变其显示,并要求你提供密码。通过插入你的卡,自动取款机过渡到另一个状态。如果你输入了正确的密码,自动取款机就会显示它的服务--取款、账户余额、转账等等。每个ATM的服务都是ATM可以转换的状态。
通过点击自动取款机提供的服务,它就会过渡到另一个状态--在那里你可以取款或转账,或检查你的账户余额。这取决于你点击什么。
如果你输入了错误的密码,自动取款机就会转换到另一个状态,上面写着 "对不起,你输入了错误的密码 "或类似的话。

程序员已经计划了ATM的每一个状态和转换。这意味着如果用户A,例如,点击ATM上的一个按钮,机器就会改变到一个特定的状态。
最近,我想通过谷歌浏览器访问我在某平台上的账户。我输入了我的用户名和密码。网站向我的手机号码发送了一个一次性代码(OTP),以确保我就是那个试图登录的人。当我点击 "登录 "时,应用程序从登录页面移开,出现了一个错误--它显示了一个空白页面。我没有地方可以输入代码。
如果有一个计划中的状态机,就可以解决这个问题。在一个状态机被很好地规划的例子中,一旦你点击签到并在你的手机上收到代码,下一个页面应该是一个有空框的页面,你可以在那里输入代码或者引发一个错误并引导你回到签到页面。
这就是状态机如何帮助你编写无错误的代码。你写的代码会设想到代码的每个状态,是什么让它过渡,以及过渡到什么状态。
如何设计状态机以编写无缺陷的代码
你在软件中出现bug的原因是由于输入发送到了错误的状态。还记得我的账户登录信息被发送到一个空白页面吗?那是因为一个低效的状态机。
为了避免这样的错误,下面是关于如何设计一个良好规划的状态机的步骤。
1.识别初始状态
在你写代码之前,确定你的应用程序成为成品时的第一个状态。作为一个例子,初始状态如签到和或注册页面。下图中的初始状态是空闲状态。闲置状态可以是签到或注册状态,也可以是两者。你应该首先确定你写的代码成为成品的初始阶段。

2.识别事件
事件是导致应用程序从一个状态转移到另一个状态的原因--过渡。事件可以是任何导致变化的东西--输入、点击、相机字幕,以及更多。例如,你在一个电子商务网站上订购了货物;该网站将你带到一个页面,在那里你可以要求运送货物。在同一个页面上,也有一个选项可以取消你的订单。订购货物或取消订单是一个事件。

识别每个可能使你的应用程序过渡的事件;这使你的代码没有错误。你会对你的代码进行编程,以允许特定的行动:是否将用户带到下一个页面或阶段--或者抛出一个错误信息,将用户带回以前的状态。
3.确定过渡
当一个输入或一个动作发生时,绘制出你的应用程序的每个状态。当用户使用你的应用程序时,该应用程序可以移动到哪些阶段?例如,你设计了一个允许用户借书的网络应用程序。应用程序的第一个状态显示一个搜索框,用户可以在那里搜索书的名字。如果用户输入了书的名字,应用程序要么把用户带到书所在的页面,要么显示:对不起,没有找到这本书,或者正在借阅。这些都是过渡--一个应用程序因为一个事件而从一个预定的状态转到另一个状态。

然而,在上面的例子中,有一个状态机应该解决的问题。如果用户输入了他要找的书的名字并按下了搜索按钮;当应用程序还在处理搜索时,用户输入了另一本书的名字并再次按了搜索按钮,会发生什么?
在这种情况下,一个具有良好规划的状态机的代码会使第二次搜索无效,直到第一次搜索完成。你根据每个状态规划的状态机可以帮助你识别bug,同时也让你处于控制之中。
为什么状态机需要从状态的角度而不是从过渡的角度来设计?
根据应用程序会陷入的状态来设计一个状态机;这样的应用程序不会遇到bug。这个设计会考虑到应用程序的每一个状态,以及在发生转换之前应该发生的每一个事件。通过这种方式,程序员写的代码较少,并能控制其应用程序。一个应用程序将只执行它被编程的功能,而拒绝其他一切。
更重要的是,一个代码将实现它背后的商业逻辑。从严格意义上讲,代码实现了它的目的。以一个读书人的应用程序为例。读书器允许用户在其中存储和阅读书籍。这就是创建该应用背后的商业逻辑。要让人们在上面保存和阅读书籍。
你在一个从过渡角度设计的状态机中写长代码。你的代码会使用大量的条件,试图适应用户可能采取的所有行动。沿着这条线,你可能会失去控制,失去对你为什么要写代码的关注。你的应用程序有可能遇到许多错误。大多数情况下,过渡在开始时是未知的。最好的办法是确定你的应用程序的状态。
结论
状态机定义和规划了一个应用程序的阶段。它是对代码应该如何工作的规划。状态机确保代码没有错误。它还能确保编写代码背后的商业逻辑得以实现。