<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何用狀態(tài)機簡化代碼中復(fù)雜的 if else 邏輯

          共 1979字,需瀏覽 4分鐘

           ·

          2021-06-05 22:05

          不知道你有沒有遇到代碼邏輯特別復(fù)雜的情況,需要很多的 if else 來判斷,每種情況有自己的邏輯。這樣的 if else 特別多以后,閱讀代碼和繼續(xù)迭代都變得很困難。如果你遇到這種代碼,會怎么優(yōu)化呢?

          本文就提供一種思路,通過狀態(tài)機來簡化復(fù)雜的 if else 代碼邏輯。

          讀完本文,你會了解到:

          • 什么是狀態(tài)機
          • 什么是狀態(tài)自動機
          • typescript 源碼是怎么利用狀態(tài)機使流程更清晰的
          • 詞法分析中的狀態(tài)機
          • 業(yè)務(wù)代碼中如何使用狀態(tài)機

          什么是狀態(tài)機

          當處理的情況特別多,我們把每種情況的處理邏輯封裝成一個狀態(tài),然后不同情況之間的轉(zhuǎn)換變成狀態(tài)的轉(zhuǎn)換。這種代碼組織形式就是狀態(tài)機。

          當每個狀態(tài)知道輸入某一段內(nèi)容時轉(zhuǎn)到哪一個狀態(tài),在一個循環(huán)內(nèi)自動進行狀態(tài)的流轉(zhuǎn)和不同狀態(tài)的處理,這種叫做狀態(tài)自動機(automation),如果一個狀態(tài)在一種輸入下只有一個后續(xù)狀態(tài),這種就叫做確定性有限狀態(tài)自動機(DFA)。

          狀態(tài)之間的流轉(zhuǎn)可以通過狀態(tài)轉(zhuǎn)換圖來表示。

          typescript 源碼中的狀態(tài)機

          typescript compiler 就是通過狀態(tài)機來組織整個編譯流程的:

          首先 tsc 劃分了很多狀態(tài),每種狀態(tài)處理一種邏輯。比如:

          • CreateProgram 把源碼 parse 成 ast
          • SyntaxDiagnostics 處理語法錯誤
          • SemanticDiagnostics 處理語義錯誤
          • Emit 生成目標代碼

          typescript 就通過這種狀態(tài)的修改來完成不同處理邏輯的流轉(zhuǎn),如果處理到結(jié)束狀態(tài)就代表流程結(jié)束。

          這樣使得整體流程可以很輕易的擴展和修改,比如想擴展一個階段,只要增加一個狀態(tài),想修改某種狀態(tài)的處理邏輯,只需要修改下狀態(tài)機的該狀態(tài)的轉(zhuǎn)向。而不是大量的 if else 混雜在一起,難以擴展和修改。

          可以看到,狀態(tài)機使得 typescript 的編譯步驟可以靈活的擴展和修改。

          詞法分析中的狀態(tài)機

          其實狀態(tài)機最常用的地方是用于詞法分析,因為每個 token 都是一種處理情況,自然會有很多 if else。

          像下面這樣用 if else 來做分詞自然也可以,這是 wenyan 的詞法分析邏輯,但是代碼很難維護。

          更好的做法是使用狀態(tài)機(DFA)來做分詞,把每一種 token 的處理封裝成一個狀態(tài)。通過邊界條件的判斷來做狀態(tài)流轉(zhuǎn),比如某個 wxml parser 分了這些狀態(tài):

          每種狀態(tài)處理一種情況的 token 的識別:

          通過狀態(tài)的變化驅(qū)動處理邏輯的流轉(zhuǎn):

          這樣不斷的進行各狀態(tài)之間的流轉(zhuǎn),當處理到字符串的末尾的時候,就完成了所有的分詞。

          業(yè)務(wù)代碼中的狀態(tài)機

          業(yè)務(wù)代碼中當遇到各種 if else 的判斷的時候同樣可以用狀態(tài)機來優(yōu)化。把每種情況封裝成一個狀態(tài),通過某一種條件觸發(fā)狀態(tài)的流轉(zhuǎn),然后在狀態(tài)機里面選擇不同的狀態(tài)處理邏輯進行處理。

          不管是游戲中不同狀態(tài)做不同的處理邏輯,還是在 ui 項目中不同狀態(tài)做不同的渲染,當代碼邏輯復(fù)雜時,難免會有很多 if else,這時候都可以用狀態(tài)機的思路來做優(yōu)化。

          這樣,當后續(xù)擴展處理邏輯、修改不同條件下的處理邏輯都變得簡單和清晰很多。

          總結(jié)

          我們首先明確了狀態(tài)機的概念:通過不同狀態(tài)封裝不同情況的處理邏輯,通過狀態(tài)的修改來完成處理邏輯之間的流轉(zhuǎn)。

          如果每種狀態(tài)都知道下一個狀態(tài)是什么,在一個循環(huán)內(nèi)自動完成狀態(tài)流轉(zhuǎn)的狀態(tài)機,就是狀態(tài)自動機,當狀態(tài)為有限個時,就是有限狀態(tài)自動機(DFA)。

          typescript compiler 就是通過狀態(tài)自動機來進行處理,封裝了很多個狀態(tài),每個狀態(tài)知道下一個狀態(tài)是什么,直到處理到終止狀態(tài),就結(jié)束編譯。

          詞法分析中一般會使用有限狀態(tài)自動機(DFA)來處理,不同 token 用不同的狀態(tài)來處理,通過輸入字符的不同來做狀態(tài)的流轉(zhuǎn),處理完字符串就完成了分詞。

          業(yè)務(wù)代碼中也經(jīng)常會有不同情況做不同的處理,這些情況在一定的條件時會做轉(zhuǎn)換的場景,比如類似開始、暫停、結(jié)束、重新開始這種。這種代碼就很適合用狀態(tài)機來優(yōu)化,不然會有很多的 if else。

          總之,當邏輯可以劃分為不同的情況,各種情況之間會相互轉(zhuǎn)換的時候就可以用狀態(tài)機來優(yōu)化,能夠免去大量的 if else,并且代碼的可讀性、可擴展性、可維護性都會有一個很大的提升。

          希望這篇文章能夠讓你知道狀態(tài)機是什么,什么時候可以用狀態(tài)機,狀態(tài)機可以帶來哪些提升,真正在代碼中用起來。

          ?? 看完兩件事

          如果你覺得這篇內(nèi)容對你挺有益,我想邀請你幫我兩個小忙:

          1. 點個「在看」,讓更多的人也能看到這篇內(nèi)容

          2. 關(guān)注公眾號「全棧大佬的修煉之路」,每周學習一個新技術(shù)

          瀏覽 61
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲青娱| 狼人色综合 | 自拍天堂 | 在线观看黄色一级电影及小说 | 99视频在线精品免费观看2 |