<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>

          如何設(shè)計(jì)一個(gè)工作流引擎

          共 2693字,需瀏覽 6分鐘

           ·

          2022-04-24 13:10

          第1關(guān)

          一天,老板找到我,說要做個(gè)簡單的工作流引擎。

          我查了一天啥是工作流,然后做出了如下版本:

          • 按順序添加任意個(gè)審批人組成一個(gè)鏈表,最后加一個(gè)結(jié)束節(jié)點(diǎn)
          • 記錄當(dāng)前審批人,當(dāng)審批完后,審批人向后移動一位
          • 當(dāng)審批人對應(yīng)結(jié)束節(jié)點(diǎn)時(shí),流程結(jié)束

          老板:簡陋了點(diǎn)。

          第2關(guān)

          老板又來了:要支持會簽節(jié)點(diǎn)。

          我又查了一天啥是會簽節(jié)點(diǎn),發(fā)現(xiàn)會簽節(jié)點(diǎn)就是一個(gè)大節(jié)點(diǎn),里面有很多審批人,當(dāng)這個(gè)大節(jié)點(diǎn)里的所有人都審批通過后,才能進(jìn)入下一個(gè)節(jié)點(diǎn)。

          我想了一個(gè)星期,推翻了原來的鏈表式設(shè)計(jì):

          結(jié)構(gòu)上我做了如下調(diào)整:

          • 把節(jié)點(diǎn)分為兩大類:簡單節(jié)點(diǎn)(上圖中長方形)和復(fù)雜節(jié)點(diǎn)(上圖中圓形)。
          • 用一棵樹表示整個(gè)流程,其中葉子節(jié)點(diǎn)都是簡單節(jié)點(diǎn),簡單節(jié)點(diǎn)都是葉子節(jié)點(diǎn)。
          • 每個(gè)簡單節(jié)點(diǎn)里都有且僅有有一個(gè)審批人。
          • 復(fù)雜節(jié)點(diǎn)包含若干個(gè)子節(jié)點(diǎn)。
          • 加入會簽節(jié)點(diǎn): 會簽節(jié)點(diǎn)激活后,所有的子節(jié)點(diǎn)都可以審批,當(dāng)所有的子節(jié)點(diǎn)都審批完畢后,會簽節(jié)點(diǎn)完成。
          • 加入串行節(jié)點(diǎn):子節(jié)點(diǎn)只能從左到右依次進(jìn)行審批,當(dāng)最后一個(gè)子節(jié)點(diǎn)審批完成后,串行節(jié)點(diǎn)完成。
          • 所有的工作流最外層都是一個(gè)串行節(jié)點(diǎn),該節(jié)點(diǎn)完成后代表整個(gè)工作流完成。

          為了控制審批流程,我設(shè)計(jì)了一些節(jié)點(diǎn)狀態(tài):

          • Ready: 可以進(jìn)行審批操作的簡單節(jié)點(diǎn)是Ready狀態(tài)。
          • Complete: 已經(jīng)審批完成的節(jié)點(diǎn)狀態(tài)。
          • Future: 現(xiàn)在還沒有走到的節(jié)點(diǎn)狀態(tài)。
          • Waiting: 只有復(fù)雜節(jié)點(diǎn)有該狀態(tài),表示在等待子節(jié)點(diǎn)審批。

          借助上述規(guī)則,一次帶會簽節(jié)點(diǎn)的工作流審批過程如下:

          老板:有點(diǎn)意思。

          第3關(guān)

          老板來了:要支持并行節(jié)點(diǎn)。

          我查了一下午啥是并行節(jié)點(diǎn),發(fā)現(xiàn)并行節(jié)點(diǎn)是一個(gè)包含很多審批人的大節(jié)點(diǎn),這個(gè)大節(jié)點(diǎn)里任何一個(gè)人審批通過,則該節(jié)點(diǎn)就完成。

          然后很快就加入了并行節(jié)點(diǎn):

          • 并行節(jié)點(diǎn)是一個(gè)復(fù)雜節(jié)點(diǎn),該節(jié)點(diǎn)激活時(shí),任何一個(gè)子節(jié)點(diǎn)都可以進(jìn)行審批,且任何一個(gè)子節(jié)點(diǎn)是完成狀態(tài)時(shí),該節(jié)點(diǎn)完成。

          加入新狀態(tài) Skip:

          • 當(dāng)一個(gè)并行節(jié)點(diǎn)的子節(jié)點(diǎn)狀態(tài)為非(Ready, Waiting)時(shí),其它兄弟節(jié)點(diǎn)及其子節(jié)點(diǎn)的狀態(tài)被置為Skip。

          舉個(gè)栗子??:

          老板:這個(gè)設(shè)計(jì)添加新節(jié)點(diǎn)還挺方便的。

          第4關(guān)

          老板又來了:節(jié)點(diǎn)要支持嵌套,比如會簽節(jié)點(diǎn)里有個(gè)并行節(jié)點(diǎn),并行節(jié)點(diǎn)里又有個(gè)復(fù)雜節(jié)點(diǎn),要可以嵌套任意層的那種。

          我:其實(shí)已經(jīng)支持了~

          • 能無限擴(kuò)展的樹形結(jié)構(gòu)可以支持任意復(fù)雜流程。

          老板:小伙子有點(diǎn)東西!

          第5關(guān)

          老板又來了:要支持條件節(jié)點(diǎn)。

          工作流附帶一個(gè)表單,要根據(jù)表單的內(nèi)容確定下一步進(jìn)入哪個(gè)分支。

          經(jīng)過幾天的冥思苦想,我加入了條件節(jié)點(diǎn):

          • 條件節(jié)點(diǎn)類似并行節(jié)點(diǎn),只不過只有滿足條件的子節(jié)點(diǎn)才能進(jìn)入接下來的審批。

          老板:已閱。

          第6關(guān)

          老板又來了:審批人多加兩種類型,比如可以從表單中選擇下一個(gè)審批人,還有根據(jù)發(fā)起人不同選擇不同的審批人。

          經(jīng)過一番考慮,我把簡單節(jié)點(diǎn)分成了3類:

          • 第一種:審批人是寫死的。
          • 第二種:審批人從表單中讀取。
          • 第三種:根據(jù)發(fā)起人和一個(gè)映射函數(shù),算出審批人。比如 get_主管("錢某") 得到錢某的主管 李某。

          老板:嗯。

          第7關(guān)

          老板又來了:節(jié)點(diǎn)可以從前往后審批,那能不能從后往前駁回?

          我: ......

          首先實(shí)現(xiàn)了駁回到發(fā)起人的功能,相當(dāng)于一切從頭開始:

          • 只有Ready狀態(tài)的節(jié)點(diǎn)有權(quán)利駁回。(就像只有Ready狀態(tài)的節(jié)點(diǎn)有權(quán)利審批一樣)

          老板:你小子偷懶。

          第8關(guān)

          老板又來了:先實(shí)現(xiàn)駁回到上一個(gè)審批人吧。

          駁回到上一個(gè)審批人其實(shí)是個(gè)很復(fù)雜的邏輯,因?yàn)楣ぷ髁髦械墓?jié)點(diǎn)可以無限嵌套,所以如何確定上一個(gè)狀態(tài)有哪些審批人并不簡單。

          犧牲了一些頭發(fā),我終于實(shí)現(xiàn)了駁回上一級的功能:

          老板:閱。

          第9關(guān)

          老板又來了:實(shí)現(xiàn)一個(gè)駁回到任意節(jié)點(diǎn)的功能。

          我發(fā)現(xiàn)這個(gè)需求并不難實(shí)現(xiàn):

          • 不斷的駁回上一級,直到Ready狀態(tài)的節(jié)點(diǎn)包含要駁回到的節(jié)點(diǎn)為止。

          老板:嗯。

          第10關(guān)

          老板又來了:在普通節(jié)點(diǎn)加一個(gè)時(shí)間限制,要是在規(guī)定時(shí)間內(nèi)沒完成就顯示已超時(shí)。

          我:還有這種需求?

          不過還是實(shí)現(xiàn)了。

          此時(shí)我明白了需求和頭發(fā)呈負(fù)相關(guān),需求越多,頭發(fā)越少。

          第11關(guān)

          老板又來了:加一個(gè)代理功能,比如有件事讓你審批,但是你拿不準(zhǔn),那就轉(zhuǎn)給拿得準(zhǔn)的人審批。

          馬上我發(fā)現(xiàn)這個(gè)需求跟以往有本質(zhì)的不同,以往的工作流的節(jié)點(diǎn)關(guān)系一開始就是固定的,就是在發(fā)起流程之前確定的,

          但是現(xiàn)在要在審批過程中更改。

          無非是加了一些班,掉了一些頭發(fā),最終設(shè)計(jì)了如下方案:

          • 代理操作的本質(zhì)是,新建一個(gè)并行節(jié)點(diǎn)作為本節(jié)點(diǎn)的父節(jié)點(diǎn),再新建一個(gè)兄弟節(jié)點(diǎn)放代理人,這樣自己和代理人都能審批通過。
          • 代理操作可以無限嵌套,即代理人也可以找人代理。

          第12關(guān)

          老板又來了:能不能再加一個(gè)取消代理的功能?

          。。。我已經(jīng)寵辱不驚了,加就加:

          • 取消代理是代理的逆操作
          • 如果代理人審批過了那就不能取消代理

          第13關(guān)

          老板又來了:給每個(gè)節(jié)點(diǎn)加個(gè)前后置條件吧,滿足前置條件才能進(jìn)入該節(jié)點(diǎn),滿足后置條件該節(jié)點(diǎn)才能審批完成。

          我的內(nèi)心:啊老板再見,啊老板再見吧再見吧再見吧!

          我的嘴:好的老板,收到收到。

          后來:后來我真的給每個(gè)節(jié)點(diǎn)加了前后置條件,與此同時(shí)審批邏輯的相關(guān)代碼增加了一倍。

          第14關(guān)

          老板又來了:現(xiàn)在有的工作流已經(jīng)非常復(fù)雜了,審批起來耗時(shí)較長,能不能對每個(gè)進(jìn)行中的工作流計(jì)算一個(gè)指標(biāo):直觀的顯示目前審批進(jìn)行的百分比。

          我:收到。

          其實(shí)跟之前的需求比起來這個(gè)并不復(fù)雜,因?yàn)椴簧婕昂诵倪壿嫷母膭樱举|(zhì)只是輸入一棵樹形結(jié)構(gòu)然后根據(jù)不同節(jié)點(diǎn)的狀態(tài)輸出一個(gè)整數(shù)。

          經(jīng)過測試思考,最終敲定的方案如下:

          • 工作流完成的百分比指的是樹中最右側(cè)Ready狀態(tài)的節(jié)點(diǎn)到最左側(cè)節(jié)點(diǎn)的距離 / 最右側(cè)節(jié)點(diǎn)的距離。

          第15關(guān)

          老板又來了:能不能給每個(gè)節(jié)點(diǎn)掛兩個(gè)可以執(zhí)行的腳本,分別在開始審批該節(jié)點(diǎn)和審批完成該節(jié)點(diǎn)后執(zhí)行?

          我:收..到。

          后來我當(dāng)然實(shí)現(xiàn)了這個(gè)功能,同時(shí)也發(fā)現(xiàn)正值壯年的我已經(jīng)禿了。

          后記

          老板是清華畢業(yè)的高才生,不然大概想不出這么多巧奪天工的需求,后來老板把這一套工作流系統(tǒng)賣給了廣*證券等公司,我也去別的公司各奔前程,當(dāng)然那個(gè)時(shí)候我以為我還有前程。

          開始做這個(gè)工作流的時(shí)候我剛剛本科畢業(yè),后來從這家公司公司離職的時(shí)候看鏡子已經(jīng)垂垂老矣。這已經(jīng)是3年前的事情了,現(xiàn)在回想起那些加班改工作流的日子,仍然心驚。

          推薦閱讀:

          世界的真實(shí)格局分析,地球人類社會底層運(yùn)行原理

          不是你需要中臺,而是一名合格的架構(gòu)師(附各大廠中臺建設(shè)PPT)

          億級(無限級)并發(fā),沒那么難

          論數(shù)字化轉(zhuǎn)型——轉(zhuǎn)什么,如何轉(zhuǎn)?

          華為干部與人才發(fā)展手冊(附PPT)

          企業(yè)10大管理流程圖,數(shù)字化轉(zhuǎn)型從業(yè)者必備!

          【中臺實(shí)踐】華為大數(shù)據(jù)中臺架構(gòu)分享.pdf

          華為的數(shù)字化轉(zhuǎn)型方法論

          華為如何實(shí)施數(shù)字化轉(zhuǎn)型(附PPT)

          超詳細(xì)280頁Docker實(shí)戰(zhàn)文檔!開放下載

          華為大數(shù)據(jù)解決方案(PPT)

          瀏覽 36
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  日日夜夜天天 | 日韩国产欧美 | 人人草在线视频 | 91久久成人 | 麻豆果传媒成人A片免费看 |