<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                > 作為一個研發,我們工作中都會處理面臨下面這些困惑: > 1. 又加需求,方法本來處理了 300 行,現在又加 50 行。 > 2. 狀態邏輯太多了,產品第 2 期又加了一個邏輯,代碼結果要調整,很頭疼。 > 3. 每個人都在吐槽,業務研發在工作中處理最多的是 `if else` ,好不容易寫個 `switch` 都能給同事吹一周。 以上三個場景應該是日常需求迭代優化中面臨最多的場景了,作為一個自稱編碼水平較高的人,總結了以下三個真實的場景,給出一些可選的方案。 ## **第一板斧:抽象事件,驅動業務** ### **核心** 梳理產品邏輯中的**主流程節點**,整理節點所**需要的依賴數據**以及節點**觸發后對應的業務邏輯**。 類比消息隊列,也是不同的業務方訂閱自己的事件源,進行不同的處理。不同點在于一個是分布式,一個是本文描述單機業務場景。 ### **實際例子** 舉一個用戶注冊之后的場景,需要: 1. 發短信 2. 發優惠券 如果用戶注冊成功之后,直接發 MQ 消息,那么用戶系統和券系統分別訂閱這個消息進行處理。不過這里討論的是在**一個項目模塊中處理完所有相關的邏輯**。 代碼將在`UserRegistered()`中一步一步去處理邏輯,之后需求又加入了**初始化 A 數據**和**初始化 B 數據**兩個需求,實現也會落到這個方法之后,最后整個代碼會越來越臃腫。 :-: ![](https://img.kancloud.cn/68/17/68176f99c1ade9744904f005e2ba91b4_432x573.png) 接下來用時間訂閱模型去化解這個點。 最后對應到程序代碼可能是這樣的: ~~~php // 事件注冊 Event::register(UserRegistered::class, [ SendSms::class, // 發短信 SendCoupon::class, // 發優惠券 InitSystemA::class, // 初始化A系統 InitSystemB::class, // 初始化B系統 ]) --------------------------------------------------------------------------------------- // 業務調用 handleRegistered($user) { $event = new UserRegistered($user); $event->fire(); } ~~~ 后面的迭代維護中,只要主流程不發生變化,那么相應的邏輯只需要去增加訂閱者去實現。 :-: ![](https://img.kancloud.cn/99/bc/99bc44b0fa54d81861933f422ef450f9_854x416.png) ## **第二板斧:有限狀態機,定義流程** 在業務邏輯數據處理這一層,很多的業務場景都與數據扭轉狀態有關,并且最后會有相應的數據實體映射。比如我們常見的: 1. 各種商品訂單(天貓,淘寶,外賣) 2. 工作流(審批,工單處理) 這類需求的特點:讀寫場景 `QPS` 不高,多數據的準確一致性要求非常高。我們底層一般直接存儲到數據庫,之上加一層簡單的數據緩存就能處理。 面臨的主要問題是,狀態太對難以維護,應該還會出現狀態的調整比如特殊場景下的狀態A到狀態Z 的扭轉。 不過業內早已給出了比較通用的解決方案,有限狀態機。 :-: ![](https://img.kancloud.cn/37/2e/372ed7e2f23fab04a4d31876f4c16535_316x426.png) ~~~ fsm := fsm.NewFSM( "created", fsm.Events{ {Name: "pay", Src: []string{"created"}, Dst: "paid"}, //支付 {Name: "cancel", Src: []string{"created"}, Dst: "closed"}, //關閉 }, fsm.Callbacks{ "after_pay": func(e *fsm.Event) { /* 支付成功調用 */ }, }, ) ~~~ 如果涉及到狀態相關的調整,在狀態機定義的地方去修改就可以解決問題。 和事件訂閱非常相似,也是集中維護,同一管理。 ## **第三板斧:n 元組配置,組合輸出** > 軟件工程沒有銀彈 -- 布魯克斯 軟件開發中我們遇到的一個一個需求都是不可預測的,我們確實很難找到一種終極的解決方案。不過本文中的討論局限在業務邏輯開發的開發套路。那么,n 元組這個簡單的概念可能算得上一個銀彈。不管業務邏輯有多復雜,在理論上我們都能抽象出 n 個字段來表達我們的數據模型。 那一個訂單舉例子,我們有如上訂單系統。不可避免,每一個業務場景,每一個邏輯,產品邏輯都可能有自己的配置和相應的處理流程,且這些邏輯都是業務迭代優化的重災區,比如: 1. 江浙滬地區包郵 2. 某一批固定的城市需要打 8.8 折 3. 雨天調價格 4. 法定節假日打樣不服務 5. VIP 身份的用戶展示文案特殊處理 每一個開發同學都曾被這些邏輯折磨的異常人痛苦,這里給出一個抽象的方案,最終每一個訂單特征都會落到具體的業務處理類,所有的類都會實現改業務場景的 `interface`,主流程只需要構造 n元祖然后獲取到相應的 interface之后進行調用。 :-: ![](https://img.kancloud.cn/a3/af/a3afd810da97a9fbc39da7caaea66fff_920x279.png) n 元祖的概念其實早已經滲透到了開發中的每一個角落,我們需要做的事情就是,在業務開發的時候真正的去思考這一層數據模型,然后加以運用,最后的代碼一定不那么 `if else`。 ## **總接** 以上三板斧在業務中使用可以很輕,也可以很重。這就意味著我們能自己寫一個簡單夠用的(對于你完全了解成長有限的業務場景),或者找一個 star 多且在維護的開源方案(對于有潛力,未來大有可為的業務)來代替。同時,這些編碼套路在各種場景下都能非常靈活的組合,比如: 1. 訂單狀態更新后觸發事件(狀態機 + 事件訂閱) 2. 不同業務線,狀態機配置,初始化放松不同(n 元組 + 狀態機) 不得不提到的一點,在漫長的業務迭代中,產品文檔會越來越缺失,最終只有通過代碼才能了解線上的真正邏輯(有時代碼過于復雜,可能就沒有人知道線上的具體情況了),集中配置,統一維護的意義之一就在于此。相信做過復雜歷史系統的交接或重構的同學對這一點都深有體會。 <br> <br> > 原文地址:https://learnku.com/articles/39302#replies
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看