成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

代碼失控與狀態(tài)機(上)

cucumber / 3252人閱讀

摘要:代碼只是狀態(tài)機圖的相關元素的一種表現(xiàn)形式,它與節(jié)點式或表格式的狀態(tài)機圖并無本質(zhì)不同。如上,狀態(tài)機是防止代碼失控的一劑良藥,制備完善的狀態(tài)機圖就是防止代碼失控的一種有效手段。

前言

前幾天和某某同學吃飯席間,他聊到每當要修改老項目中自己寫的代碼時就痛苦不堪,問我是不是也有同感。我覺得這應該是不少程序猿的心聲,之所以會這樣,大致有兩個主因:

項目的整體設計很糟糕,只管往上堆砌各種功能、補丁,對于代碼質(zhì)量和結構關系基本無暇顧及,最終積重難返滑向失控。

對技術缺乏必要的敬畏心,基礎不夠扎實、知識面較窄,不能(無法)進行合理的規(guī)劃,最終導致停留在低水平的代碼堆砌上,只求完成功能就萬事大吉。

程序猿飯桌上總少不了對產(chǎn)品經(jīng)理的吐槽:“產(chǎn)品經(jīng)理又對業(yè)務流程進行了瘋狂調(diào)整,我覺得這會導致狀態(tài)機無法支持了?!彼倪@個槽點讓我一時有些語塞,倒不是懷疑產(chǎn)品經(jīng)理的腦洞還能大到把狀態(tài)機開到失控,只是詫異難道我們還有比狀態(tài)機更適合應對業(yè)務流程變更的武器嗎?

事實上狀態(tài)機對于軟件工程師來說應該是個很基礎的知識點,它原理簡單卻擁有強大的適應力并被廣泛應用(譬如:游戲開發(fā)、工作流、編譯器、正則表達式等解析器),掌握好它的原理和應用,能幫助我們從容應對很多棘手問題,它于程序猿應對復雜流程性問題,就好比醫(yī)生使用抗生素應對細菌感染一樣的最佳武器。同時,它還是防止代碼失控的一劑良藥。

基本概念

狀態(tài)機一般泛指“有限狀態(tài)機(Finite State Machine)”,《離散數(shù)學》中有關于它的專門章節(jié),以下謹為我對相關概念的形式上的非精準釋義,如有出入請以教科書或相關學術資料為準。

狀態(tài):顧名思義表示某個時刻系統(tǒng)處于一個特定的階段。通常我們不考慮中間態(tài),也可以把中間態(tài)進行退化處理。當狀態(tài)發(fā)生變更,就叫狀態(tài)轉(zhuǎn)換(Transfer)或狀態(tài)遷移(Transition)。

事件:驅(qū)動系統(tǒng)進行狀態(tài)轉(zhuǎn)換/遷移的源,提供這種源的也常被稱為“觸發(fā)器(Trigger)”。

行為:當系統(tǒng)進行狀態(tài)轉(zhuǎn)換時進行的響應處理,提供響應處理的程序也常被稱為“處理器(Handler)”。

有了上面的基本概念,我們來看一個最簡單的狀態(tài)圖:

你可能會奇怪這個圖怎么跟網(wǎng)上那些狀態(tài)機圖不一樣,連狀態(tài)轉(zhuǎn)換條件都沒有呢?這是因為,我覺得在了解狀態(tài)機之前,最好先確立以下兩種概念:

狀態(tài)驅(qū)動:狀態(tài)機負責根據(jù)輸入來驅(qū)動狀態(tài)流轉(zhuǎn)。

遷移判定:在狀態(tài)流轉(zhuǎn)過程中確定當前狀態(tài)是否需要進行轉(zhuǎn)換/遷移,以及轉(zhuǎn)換/遷移到哪個狀態(tài)中的判定機制。

所以,在常見的狀態(tài)機圖中標注的那些狀態(tài)轉(zhuǎn)換條件只是“遷移判定”的一種具體表現(xiàn)形式,它即可以由狀態(tài)機內(nèi)置,也可以是獨立的判定器來處理,又或者由狀態(tài)圖預先定義好,如此等等。

建立“狀態(tài)驅(qū)動”和“遷移判定”這兩個被抽象化的概念,有助于我們深入理解狀態(tài)機的機理,并且對我們設計一個魯棒性和擴展性更好到狀態(tài)機有實際指導意義。

狀態(tài)機圖

以下是表示一個‘簡陋’的 Email 地址格式的解析器狀態(tài)圖,狀態(tài)遷移條件采用正則表達式來表達,其中圖二又稱為“狀態(tài)遷移圖”。

圖一:節(jié)點式

圖二:表格式(紅色格表示拒絕或異常;灰色格表示忽略或無意義;其他格表示遷移條件)

代碼實現(xiàn)

有了上面的狀態(tài)圖,就像建筑工人拿到了詳細的建筑設計圖紙;現(xiàn)在我們只需要對著狀態(tài)機圖,把它映射成代碼即可完成一個基本狀態(tài)機。狀態(tài)機圖越詳細,實現(xiàn)起來就越容易,同時代碼的可維護性也越好。

public class Email
{
    public string Identifier { get; private set;}
    public string Host { get; private set; }
    public string Domain { get; private set; }

    private Email() {}

    public static Email Parse(string text)
    {
        if(string.IsNullOrEmpty(text))
            return null;

        var state = State.None;

        /* The State-Driven */
        for(int i=0; i

上面的代碼雖然看起來沒什么技術含量,但它已經(jīng)具備了一個狀態(tài)機最基本的三大要素了(狀態(tài)、狀態(tài)驅(qū)動、遷移判定),針對具體業(yè)務場景我們只需完善和優(yōu)化它的程序結構,底層原理的基本要義其實就是這么簡單。

失控的大腦

人腦是一個很神奇的存在,它很擅長處理抽象思維,對于邏輯推理也有很好的應對能力,但卻有個不擅長處理并發(fā)任務的Bug。比如當面臨很多個邏輯分支,各分支的判定條件彼此關聯(lián),大腦很快就會陷入繁雜的狀態(tài)中無法自拔。

表現(xiàn)在解決復雜流程相關的任務時就是,寫著寫著你會發(fā)覺腦子好像不夠用了,而程序中的 Bug 卻像打地鼠游戲中的老鼠一樣層出不窮。不難想象,即使腦力過人的你在勉強寫完后的某天,產(chǎn)品經(jīng)理帶著他的腦洞又來找你了,在他的威逼利誘下你打開了一個月前的代碼,忽然,覺得還是抱著產(chǎn)品經(jīng)理同歸于盡算了……

這大概是某某同學,面對自己曾經(jīng)的代碼時痛苦的根源所在,因為普通人面對復雜流程問題時,終歸受人腦算力所限。本質(zhì)上這是人腦算力有限的一個困境,人類解決這個困境的一個行之有效的辦法就是“分而治之”,即將一個大問題或復雜問題不斷進行分解分化,直至達到人腦能相對輕松理解和處理的程度。

為什么說狀態(tài)機是解決此類問題的一劑良藥?

通過狀態(tài)機圖可以很容易的看到它天生具有“分解分化”的特征,一個復雜的流程由多個流程節(jié)點組成,這些節(jié)點可以理解為對流程的分解,流程節(jié)點之間的轉(zhuǎn)移條件(遷移判定)可以看成是被分化后的邏輯分支,如果大腦直接處理整個流程很容易陷入紛擾的流程分支和各種細節(jié)中,但是,當我們把眼光聚焦在某個流程節(jié)點和它的轉(zhuǎn)移條件上的時候,大腦需要處理的信息量就變得非常少了。

所以,當我們直面一個繁雜的流程圖的時候,第一感覺就是復雜、腦闊痛,這其實是大腦的正常反應,當你把眼光聚焦到“Start”節(jié)點上,并順著它往下推,每個節(jié)點的信息量一定是大腦能輕松處理的量級,這種順藤摸瓜的方式反過來也正是流程設計的套路。我有時會被自己剛畫完的狀態(tài)機圖給驚訝到,怎么這么復雜?因為當我一點點把細節(jié)補充上去后,整體性自然會變得復雜了,但是局部依然是簡單的,而簡單就是可靠、魯棒、可維護性的同義詞。

代碼只是狀態(tài)機圖的相關元素的一種表現(xiàn)形式,它與“節(jié)點式”或“表格式”的狀態(tài)機圖并無本質(zhì)不同。

另外,狀態(tài)機圖相對代碼而言,它更專注于流程本身,而代碼畢竟是具體實現(xiàn)層面的東西,除了流程本身還包括程序結構、業(yè)務代碼等與流程無關的代碼,這些額外的東西對我們解讀流程造成了干擾,因而相對純粹的狀態(tài)機圖就好比是代碼實現(xiàn)的“地圖”。

經(jīng)過一段時間后,我們可能已經(jīng)不記得實現(xiàn)細節(jié)了,這時看著狀態(tài)機圖來進行代碼解讀和修改將會大大提高效率和準確度,這就是提升代碼可維護性的有力手段。

如上,狀態(tài)機是防止代碼失控的一劑良藥,制備完善的狀態(tài)機圖就是防止代碼失控的一種有效手段。

課后作業(yè)

試著脫離狀態(tài)機圖擼一個“成員訪問表達式”的解析器去體驗下失控的感受。下次,我們將一起來實現(xiàn)這個東西。

附注:

成員訪問表達式:訪問對象方法、屬性、字段、索引器(包括字典、列表)這些成員的表達式,其中方法和索引器(包括字典、列表)的參數(shù)支持常量和成員表達式(即表達式遞歸)。詳細的文法請參考C#語言手冊。譬如:

PropertyA
.ListProperty[100]
.MethodA(PropertyB, "StringConstant for Arg2", 200, ["key"])
.Children["arg1", "arg2"]

如果你覺得這次的文章對你有所幫助,又或者你覺得我們的開源項目做的還不錯,請為我們點贊并關注我們的公眾號。

提示

本文可能會更新,請閱讀原文: https://zongsoft.github.io/blog/zh-cn/zongsoft/coding-outcontrol-statemachine-1,以避免因內(nèi)容陳舊而導致的謬誤,同時亦有更好的閱讀體驗。


本作品采用?知識共享署名-非商業(yè)性使用-相同方式共享 4.0 國際許可協(xié)議 進行許可。歡迎轉(zhuǎn)載、使用、重新發(fā)布,但必須保留本文的署名 鐘峰(包含鏈接:http://zongsoft.github.io),不得用于商業(yè)目的,基于本文修改后的作品務必以相同的許可發(fā)布。如有任何疑問或授權方面的協(xié)商,請致信給我 ([email protected])。

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/42154.html

相關文章

  • OWASP 10 大 Web 安全問題在 JEE 體系完全失控

    摘要:希望引起大家這些安全問題的足夠重視。允許攻擊者在受害者的瀏覽器上執(zhí)行腳本,從而劫持用戶會話危害網(wǎng)站或者將用戶轉(zhuǎn)向惡意網(wǎng)站。 雖然,JavaEE 內(nèi)置了一些非常優(yōu)秀的安全機制,但是它不能全面應對應用程序面臨的各種威脅,尤其許多最常見的攻擊:跨站攻擊(XSS),SQL 注入,Cross-Site Request Forgery (CSRF), 與 XML eXternal Entities...

    Cc_2011 評論0 收藏0
  • “分庫分表" ?選型和流程要慎重,否則會失控

    摘要:但你是否知道分庫分表需要哪些要素拆分過程是復雜的,提前計劃,不要等真正開工,各種意外的工作接踵而至,以至失控。在實施分庫分表策略時,這些個性會造成策略過大不好維護。 更多文章關注微信公眾號《小姐姐味道》 https://mp.weixin.qq.com/s?__... 數(shù)據(jù)庫中間件之分庫分表 恭喜你,貴公司終于成長到一定規(guī)模,需要考慮高可用,甚至分庫分表了。但你是否知道分庫分表需要哪...

    archieyang 評論0 收藏0
  • 活動實錄|工具化、產(chǎn)品化、運營化——「美團點評」運維團隊背后的故事

    摘要:今天我將美團點評這幾年在運維方面做的一些工作,以及自己的思考與大家分享一下。所以在美團點評給自己的使命,就是要把美團點評的運維做到騰訊百度的水平,把缺失的過程成長的過程由自己做出來。美團點評的自動化工具講一下美團點評的自動化工具。 數(shù)人云當西方的SRE遇上東方的互聯(lián)網(wǎng)Meetup第一彈實錄來啦! 本次分享嘉賓是美團點評運維中心高級總監(jiān)鐘紅軍,他向我們詳細介紹了美團點評近3年來在大規(guī)模運...

    pinecone 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<