深耕業務 ---- 探索複雜/超複雜前端業務的開發與設計

  同步更新博客:前端

    1. 知乎專欄:前端路上的摸索vue

    2. github:designreact

  距離上一篇博客,我已經有3個月沒有寫博客了,腦子裏也有不少靈光和新點子,忙嘛,確定忙,可是忙不是理由,因此見諒。此次給本身下了死命令,必定要產出點東西,so,將本身最近開發中能總結的東西慢慢再搞出一點。git

    PS:這是一篇思惟參考性的文章,比較枯燥,閱讀時間30分鐘(包括思考和印證)程序員

  做爲深耕的業務,咱們就從一個我遇到的複雜需求開始作個引子。栗子以下(可先看圖片過個眼癮):github

  需求列表以下:後端

  1. 有20種不一樣類型的活動,每種活動按鈕文字不同
  2. 每種活動根據活動狀態有不一樣的show和hide方案(最多有3-4個字段,分別控制)
  3. 根據不一樣業務狀態,定義按鈕的展現方式(禁用? or 可用?)
  4. 每一個不一樣按鈕的功能都不同
  5. 同一個按鈕,根據不一樣活動也有不一樣的功能(好比調整優惠,針對不一樣活動,引用不一樣組件)
  6. 一個按鈕,相同的功能,可是請求的接口和參數也是不同的(老數據老接口,新數據新接口)

 

  通常要求:這是一個遷移不完整的入口項目,對接全部活動的詳情和操做,考慮業務不穩定性(業務變更須要變動,例如新遷移活動須要增長新的操做)以及迭代(繼續遷移其餘老項目,對接上來),須要考慮到更簡易的拓展以及敏捷操做,固然維護和開發的成本也須要考慮的。數組

 

  更高要求:瀏覽器

  1. view視圖上,簡潔清爽,各類邏輯判斷不亂
  2. vm層,避免超繁瑣,代碼的邏輯和歸類清晰明瞭
  3. 低耦合,達到更鬆散的控制,對於之後拆分和開發更敏捷
  4. 輕鬆的統一管理,能夠統一管理

 

  相信你們看了這個需求和要求,每一個人根據本身的程序員開發經驗和設計經驗上,每一個人都有不一樣的解決方案。其實,每一個解決方案都是一種方式,只是在不一樣角度上的實施的成本以及設計思惟上的不一樣。So,我想分享給你們的,也是通過我思考後以及完善的一種解決方案,拿出來僅供你們參考。架構

 

  程序員寫的全部代碼全都服務於業務,這個毋庸置疑。可是我想先問你們一個問題,到底什麼是業務?

 

  在老闆眼中,業務就是我賺錢的工具;在銷售員眼中,業務就是我須要完成的指標;在產品眼中,業務就是我要實現完成的需求…每一個人對業務的理解都不同,可是,有誰考慮過,在前端開發工程師眼中的業務究竟是什麼???


  下面是我站在前端的角度去理解的業務,以下:

 

  so,在個人理解裏,我把前端所寫的業務拆分紅這6大部分:

    1. 業務數據:負責獲取業務數據
    2. 業務邏輯:實現產品所定義的規則
    3. 邏輯數據:經過一系列規則所產出的邏輯數據
    4. 視圖數據:經過邏輯數據轉換成視圖數據(不將邏輯和視圖直接綁定)
    5. 視圖展現:經過視圖數據,直接驅動視圖層展現對應視圖
    6. 視圖功能:經過視圖展現組裝成的需求功能

 

  在簡單的業務需求中,可能我拿到的後端數據,就直接能夠去渲染視圖層,而後就完善功能。從開發的成本和複雜度上考量上,是不值得去作業務拆分。因此,在複雜的業務需求中以及兼顧拆分和維護中,這種業務方法論就能夠大展手腳了。如下,我就拿開頭的例子,詳細解析圍繞業務的6大部分的設計。

 

具體實現步驟:

  1. 在現代框架中(vue、react、angular),最核心、也最靈活的處理視圖變化的方式,就是將驅動的視圖的數據作成可配的,因此第一步,咱們將咱們按鈕的需求作成數據配置,代碼以下:

      ps:將按鈕的數據,全都裝配到一個數組中,而後數組中的子集封裝一個配置對象,將按鈕的文字、回調、是否禁用等功能裝配到模板中了

 

  2. 首先在個人需求中數據的獲取只有一個接口,不復雜,因此對於業務數據的獲取來講我沒有將這個部分進行拆分管理。

      ps:很簡單的前端數據請求,由於改處的接口,在其餘動態刷新數據的時候還須要,因此這裏我將請求封裝成一個單一函數,只獲取業務數據

 

  3. 對於最終視圖展現,咱們須要一個視圖數據去驅動。有時候,咱們會將咱們業務規則產出的數據直接掛載到視圖數據上,而後經過業務邏輯產出的數據直接驅動視圖。不過在個人設計中,不建議將視圖數據=邏輯數據。由於這樣,咱們的視圖數據和邏輯數據會產生一種強依賴關係,並且,有時候邏輯數據只是根據業務定義出來的,而不是最適合作視圖數據,來渲染數據的。若是邏輯出問題,或者前置的數據(直白的就是獲取後端接口數據)出問題,那麼強依賴的視圖除了出問題,有時候甚至會直接崩潰。因此每次在視圖數據和邏輯數據中我會作一層數據轉換。

      ps:tempData爲視圖數據,在這裏對每一個業務數據進行處理,而後對視圖數據進行賦值,在處理中,能夠對業務數據進行容錯處理,無論業務邏輯怎麼變化,或者業務數據怎麼變化,在個人視圖數據層面來講,就算你掛了,我依然能夠對個人視圖進行驅動,頂可能是默認值,而不會直接宕機。必定程度上,增加了代碼的健壯性。

 

  4. 咱們再從上面的代碼看咱們的業務邏輯,咱們全部的邏輯,都統一拆到了視圖數據的右邊了,好比咱們討論的按鈕邏輯,因此對於整個頁面功能來講,個人按鈕的業務邏輯與全局全部功能的耦合,只有一個地方。這樣的設計,秉承低耦合的思想,沒那麼強的控制慾,很鬆散,很舒服。

      ps:紅框的地方爲按鈕的業務邏輯。

 

  5. 下面爲拆分的按鈕邏輯,從軟件工程的設計佈局上,將邏輯拆到最外層,和其餘配置文件,枚舉文件同級(我的感受方便順手)。 

      ps:在工程中建立邏輯存放地方

 

  6. 在真正業務使用的地方,將業務邏輯代碼和其餘統一管理文件引入進來。

      ps:該處引入了全局統一管理枚舉值、按鈕拆分邏輯以及邏輯的適配器

 

  7. 由於考慮到,咱們的活動自己的業務,2個大類(店鋪和單個商品活動)+7個小類(不一樣活動)+不一樣活動渠道(6種渠道)共20多種活動的需求,因此針對活動以及活動數據的共性去統一處理勢必會致使邏輯混亂,數據混亂,代碼混亂,各類if和嵌套if等等,因此該處引入狀態機機制,羅列全部存在的活動。

      ps:狀態機中針對類型+渠道肯定活動,每一個到葉節點的狀態包裝該活動對應的業務邏輯,而針對這個活動類型通用的業務數據,都包裝在活動類型的節點下。

 

  8. 咱們詳細看每一個活動下的按鈕邏輯,咱們在按鈕邏輯中,將對每一個按鈕所要作的功能仍是未知的,可是咱們知道按鈕所要作的事情的類型,因此咱們在這裏將定義按鈕的文字、文字的行爲、屬於這個按鈕功能附帶的數據。而後再經過傳入進來的業務數據,根據業務邏輯,產出邏輯數據。

      ps:font爲按鈕的文字、behavior爲該按鈕須要作的行爲,data爲操做這按鈕以後須要附帶的一些數據。而後再根據業務邏輯規則,產出一個活動下的邏輯數據,供視圖數據使用

 

  9. 這樣咱們就能夠根據不一樣規則,加載不一樣狀態機中的不一樣邏輯,好比這段狀態機輸出代碼,我須要按鈕邏輯,我就匹配按鈕的邏輯,我須要匹配整個活動下共有的圖片數據,我就直接加載活動類型的狀態機。

      ps:加載狀態機對應的邏輯規則,這樣咱們就徹底把邏輯拆分出來了。

 

   10. 徹底拆分的按鈕邏輯,就成了單個點了,可是這個邏輯只定義的按鈕所須要的行爲,對於按鈕具體行爲的實現沒有涉及。我在設計按鈕具體實現的時候,考慮到按鈕的全部實現,都在一個頁面中,須要直接調用一些業務數據和視圖數據操做視圖變化以及邏輯數據改變,因此,在個人項目中,沒有將行爲的實現拆分出去。下面就是我定義的對應按鈕的行爲的列表和具體實現:

      ps:直接在vue的methods中定義按鈕邏輯所須要行爲

 

  11. 按鈕業務邏輯設計完畢,預留功能接口。內部組件定義行爲的具體的實現,開放功能的對接。下面就須要一個適配器,將定義和實現牢牢鏈接在一塊兒。這個按鈕適配器,就是將按鈕的產出的邏輯數據和具體的實現鏈接,真正產出邏輯數據

      ps:經過適配器,將定義和實現進行單獨拆分。而後銜接出邏輯數據

 

  12. 而後將最終蒐集到的視圖臨時數據,綁定到真正的視圖數據上去渲染視圖,這樣咱們就獲得了完整的業務須要的視圖。用戶點擊按鈕就能操做視圖的功能,根據按鈕拆分中得附帶數據,去判斷用戶具體去操做哪一個按鈕,這個按鈕的什麼功能,以及須要請求不同的接口,接口數據等等

      ps:data爲附帶數據,數據中定義的什麼字段有什麼用,就根據本身的業務需求來。

 

因此總體設計,能夠歸類成下面的一張圖片:

 

根據這張思路的設計圖,能夠將這裏的複雜需求進行拆分,而後對應問題解決業務上的需求點:

  1. 20種活動,使用狀態機輸出每種活動展現的不一樣按鈕文字
  2. 在狀態機下,根據業務數據統一作按鈕的hide和show的業務邏輯包括禁用和可用的邏輯。產出邏輯數據
  3. 每一個狀態機的按鈕定義用戶行爲,在行爲實現中實現
  4. 在狀態機中根據行爲+附加數據肯定一個按鈕實現的不一樣功能,包括其餘差別化的方案(好比請求不一樣接口)
  5. 狀態機+實現接口產出不一樣數據的拆分,對於業務的不穩定性和迭代兼容有很好的適用。鬆散的控制和低耦合的狀態,對於活動的增長和刪除,功能按鈕的刪除和增長,以及按鈕功能實現的增長等,更方便開發和操做
  6. 由於view作成可配,全部狀態都在業務邏輯層實現,直接產出邏輯數據來驅動視圖數據,因此view層簡潔清爽
  7. 狀態機統一管理業務邏輯和行爲,實現接口統一管理行爲實現

 

  這只是我在業務開發生涯中,最近總結出來的一種業務方法論,這是一種針對複雜和超複雜的業務的一種探索,上面只是一個需求中的案例,你們能夠根據本身的案例參考這種方法論。具體業務特性具體把握,好比最初設計規模,持續增加規模,以及將來發展規模(是否須要拆分)等。

 

如下爲我參考的一些思想:

  1. 單體架構和微服務架構
    a) 單體架構(monolithic architecture)的應用,各組件的代碼是做爲一個總體存在的,組件之間互相合做,共享內存和資源。
    b) 微服務架構(microservice architecture)則是由許許多多個互相獨立的小應用組成,每一個應用都有本身的內存空間,應用在擴容時也是獨立於其它應用進行的。

 

  2. 瀏覽器事件設計思想
    a) 事件思想:瀏覽器的事件通常都是用戶觸發而後去觸發開發者的實現。因此,在瀏覽器自己的設計中是不知道用戶究竟是怎麼實現的。So,瀏覽器的事件設計的時候就是在瀏覽器中定義一個行爲(click or 其餘),而後經過一個適配器,也就是註冊事件的方法,將行爲的實現進行適配和組裝

 

  3. 流程化管理
    a) 流程化管理是指以流程爲主線的管理方法。前端從數據獲取到最後的視圖功能展現,包括中間的各類業務邏輯以及視圖渲染等等,都是一系列的流程,流轉出來的結果。so,並且拆分也能夠根據這些子節點中的流程做爲關鍵點進行拆分。

 

  4. 敏捷開發思惟
    a) 敏捷開發以用戶的需求進化爲核心,採用迭代、按部就班的方法進行軟件開發。敏捷,存在的目的就是因地制宜的去根據本身的項目去評估和拆分。相似於這套方法論,因我的和項目去評估到底怎麼拆分,而不是拉過來就是幹滿一套。

 

以上只是我深耕業務過程當中本身總結的一套思想和方案,僅供你們參考。並且這套方法論也可能不是很完善,能夠一塊兒討論和繼續深刻的探討。

相關文章
相關標籤/搜索