提效新紀元-元件化開發在轉轉App中的應用-後端篇

架構師修行手冊發表於2023-05-11

來源:轉轉技術


  • 1 前言

  • 2 背景

  • 3 現狀分析

    • 3.1 對接流程與開發流程

    • 3.2 專案進展

    • 3.3 問題彙總

    • 3.4 問題切入點與解決方案

  • 4 走進元件化開發

    • 4.1 元件定義

    • 4.2 元件分類

    • 4.3 元件模型

    • 4.4 元件特點

    • 4.5 元件化開發

    • 4.6 元件化開發的型別

    • 4.7 元件化開發的優勢

  • 5 元件化開發的落地過程

    • 5.1 前置工作

    • 5.2 元件粒度

    • 5.3 元件類設計

    • 5.4 引數傳遞

    • 5.5 元件命中條件

    • 5.6 管理多版本元件

    • 5.7 元件排序

    • 5.8 元件驅動

    • 5.9 新的開發模式

  • 6 效果資料

  • 7 輔助生態

  • 8 總結

  • 9 參考文獻

1 前言

元件化開發是一種利用可重用的軟體構件來設計和開發計算機系統的過程。藉助元件化開發可以實現最小化、高效交付。

平臺基礎體驗部將業務邏輯抽象為元件,透過組合元件快速構建商品Feed流,研發效率整體提升2倍。元件化開發不僅帶來效率的提升,同時極大地增加了程式碼複用性、降低了系統的複雜性等等。本文將詳細介紹元件化開發的落地過程,為大家揭曉轉轉App快速迭代的奧秘。

2 背景

平臺基礎體驗部主要承接轉轉App、小程式迭代。

2021年底,基於轉轉定位於“有質檢、放心買賣的二手交易平臺”的背景,對首頁Feed(Feed,即:商品列表頁)、主搜Feed整體改造。排期時,我們發現商品卡片渲染投入耗時過多,無法完成春節前交付。短期解決方案,可以額外投入人力,按期交付。但考慮未來還會整體改版,需要尋求一種方式,能夠快速承接全平臺範圍產品迭代。

2022年3月,我們著手策劃新方案,並構建出一套元件化開發流程。

2022年9月底,距離轉轉集團宣佈品牌升級還有一個月的時間,App、小程式需要整體換新,其中僅Feed功能點,升級多達20幾處。元件化開發藉此契機,開始大範圍應用,效果得到了印證。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

3 現狀分析

3.1 對接流程與開發流程

需求正式評審後,進入介面評審階段,日常對接流程如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

開發同學小張,根據App首頁UI圖例定欄位後,同步給native以及QA。隨後著手另一功能點:App收藏夾推薦,定欄位、同步欄位。

介面評審後,進入開發,開發流程如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

RD小張開發首頁時,首先獲取各業務的RPC資料,然後自上而下寫好資料渲染邏輯。完成自測後,提供給native、QA測試環境。緊接著,投入到收藏夾功能點開發,流程類似。

看似十分順暢的流程,在執行過程中並不順利,總會有一些“小插曲”,比如:

(1)UI中出現了橫排卡片樣式,卡片上多了一個心智元素,native小劉要求增加一個userText欄位。

(2)同一個UI在小程式上卻要使用不同的商品圖尺寸,FE小方大喊:給我返回16×16的尺寸!

(3)小張忙得不亦樂乎,小趙過來支援,給商品圖欄位定義為infoImage,與此前的image欄位命名不同,QA小張、native小李很生氣,表示我不能接受,欄位不統一難於維護。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

對接流程問題多多,開發流程當然也沒有想象的那麼順利。PM會提出一些臨時要求:在某些功能點上增加AB實驗,或者調整某處功能點的展示邏輯。RD在實現過程中可能會調整元素的渲染順序,進而影響全域性資料渲染正確性,為了避免程式碼調整引入額外的缺陷,QA的測試的用例也會變多。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

3.2 專案進展

進入開發前,RD基於現有的改動點做出技術評估,輸出排期。以App首頁、App收藏夾推薦為例,從產品規則上看,只有RPC資料來源不同,RD認為大部分邏輯是可以複用的。所以,功能相近的位置可能會適當的減少排期。

但實際開發中,新的程式碼邏輯與歷史邏輯存在衝突,無法順利的融入到資料渲染程式碼塊。各介面的實體類定義五花八門,複用某些資料渲染方法時,存在很多實體之間的資料轉換,程式碼顯得十分臃腫。很多無法預知的“小插曲”導致原本答應產品在10個工作日內完成20個Feed改造,即使加班也無法按時交付。其他職能的進度也會受到影響,給整個專案帶來風險。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

3.3 問題彙總

回顧對接、開發流程,主要暴露以下幾個問題:

  • 版本、終端、UI差異增加了程式碼的複雜性,難以複用:RD為了適配各端不同的樣式,或者相容native產生的線上問題,或者為了相容不同版本的樣式,往往要寫很多控制邏輯,使得程式碼邏輯越來越臃腫,複雜性與維護成本逐漸增加。

  • 介面返回值欄位不統一:因為開發人員的命名習慣不一致,隨著介面的增多、產品的不斷迭代,可能會出現多個欄位描述同一個功能點的情況。介面欄位數量成爆炸式增長,難以維護。出現問題時,RD很難快速定位欄位,溝通成本、認知成本也會大幅增加。

  • 無法適應產品快速迭代:AB方案的加入、產品邏輯的調整使得元素的渲染邏輯過於龐大,元素之間的依賴關係變得更加複雜,RD無法快速交付。

  • 工作內容重複,排期長,易引入延期風險:很多功能點十分相似,但是開發中無法完美複用,使得排期較長。過長的排期外加無法預知的隱藏問題,很有可能帶來延期風險。

3.4 問題切入點與解決方案

  • 切入點

(1)RPC模組、資料渲染邏輯中,有些內容完全一致,如果將他們劃分為模組,將大幅增加程式碼的複用性。

(2)資料渲染資料是過程化的、自上而下的,如果能夠打破這種序列開發模式,各資料渲染邏輯之間的耦合性大幅降低。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

(3)深入觀察單一資料渲染內部,如果將版本相容、終端差異、AB實驗等從資料渲染邏輯中剝離,只留下核心邏輯,資料模渲染更具複用性。

(4)不同元素的資料渲染邏輯之間難免會存在依賴關係,需要有一種資源編排機制,能夠將各資料渲染邏輯按規則組織起來。

提效新紀元-元件化開發在轉轉App中的應用-後端篇
  • 解決方案

結合相關的技術調研以及業界相關的經驗,我們引入了《元件化開發》,即:基於元件的開發。元件、元件化開發帶來的優勢能夠達成我們的訴求,元件、元件化開發具體是什麼,具有什麼優勢?接下來將具體展開描述。

4 走進元件化開發

4.1 元件定義

元件是一組功能相關的邏輯、資料的聚合。

元件是自包含和完備的,通常以一組完備的API形式開放給使用者,使用者不需要了解元件內部的邏輯,只需要關注API的使用,元件的實現邏輯和依賴由元件自己負責。

4.2 元件分類

  • 按職能可將元件分為:技術元件和業務元件。業務元件是把一組相關的業務邏輯封裝為一個元件,也稱為管理邏輯元件。

  • 按層次可以分為:框架元件、平臺元件、通用管理邏輯元件、領域管理邏輯元件、行業管理邏輯元件、個性化管理邏輯元件等。

  • 按來源可以分為:開源元件、商業元件、自研元件等。

4.3 元件模型

元件需要遵守元件模型協議。元件模型是一組標準。維多利亞大學電子與計算機工程系給出的元件模型如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

元件模型包括:介面列表、命名、後設資料、互通性、自定義元件介面、組合介面、元件演進、打包與部署。

4.4 元件特點

一個設計良好的元件應該具備如下幾個特點:

  • 可管理:元件是基於統一的模型進行設計和實現,遵循統一的技術規範,由統一的後設資料進行描述,有清晰的分類和分層,可由元件工具進行統一管理,以規範一致的模式進行使用。

  • 可複用:可複用是元件的一個核心特點。通常元件都是經過良好的設計和封裝的,可以被多個場景複用。只有能夠複用,才能更好地發揮元件的價值。

  • 可配置:為了更好地複用,元件在不同的場景下使用時不需要去修改元件自身,通常元件需要把不同場景下可能會變化的部分作為可變引數,允許使用者透過配置不同的值,來滿足不同使用場景下的需求,使元件具有更好的可複用性。可配置的內容通常包括環境資訊、引數、規則、模型屬性等。

  • 可擴充套件:在使用元件的過程中,當透過配置也無法滿足場景化的使用需求時,元件的可擴充套件性就變得尤其重要,如果一個元件不具備可擴充套件性,將極大降低元件的複用價值。元件的擴充套件性通常可以透過良好的設計來實現,如支援繼承,可區域性邏輯重寫;支援事件,透過前置後置事件,允許使用定製規則和邏輯,就可以更好地滿足不同場景下的個性化使用需求,提高元件的可複用性,發揮出元件更大的價值。

4.5 元件化開發

元件化開發: 元件化開發,即:基於元件的開發(Component-Based Development,簡稱:CBD),是一種利用可重用的軟體構件(元件)來設計和開發計算機系統的過程。

元件化開發的起源: 元件化開發出現於20世紀90年代末。當時物件導向建模開發(Object-Oriented,簡稱:OO)沒有像最初建議的那樣被廣泛的重用。OO產生了大量細粒度的類、物件和關係,在這些較小的單元中發現可重用的部件是非常困難的。CBD背後的思想是整合相關的部分並對它們進行集體重用。

4.6 元件化開發的型別

元件化開發分為兩類:機會式重用、帶有開發量的重用。

  • 機會式重用:根據已有的元件組合成一套系統。
提效新紀元-元件化開發在轉轉App中的應用-後端篇
  • 帶有開發量的重用:根據需求,定製開發某些元件,然後將元件組合成一套系統。
提效新紀元-元件化開發在轉轉App中的應用-後端篇

在日常的使用場景中,因為產品不斷地迭代,使用現有元件直接組合成系統的場景較少,帶有開發量的元件重用應用場景更為廣泛。

4.7 元件化開發的優勢

  • 最小化交付:基於現有的元件,即可裝配成系統。

  • 高效:開發人員可以更集中關注需求變更點,快速完成產品升級。

  • 提升系統質量:開發人員可以有更多的時間來確保系統質量。元件的高質量決定了系統的質量。

  • 減少支出:減少資源投入。

5 元件化開發的落地過程

藉助元件化開發思想,我們構建了一套元件化開發架構,內部稱之為:星環,整體架構如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

星環體系可以總結為兩層一包:宣告層、驅動層以及業務元件包。

  • 宣告層:包含基礎宣告、RPC模組宣告、元件宣告、降級觸發規則宣告。基礎宣告以Java程式碼形式宣告,剩餘部分以XML形式宣告。

(1)基礎宣告:定義了應用名、應用上下文、請求引數、元件的驅動方式等。

(2)RPC模組宣告:定義了應用中包含哪些RPC引用,RPC模組之間的依賴關係。

(3)元件宣告:定義了應用中包含哪些業務元件、元件的屬性、元件的觸發條件。

(4)降級觸發規則宣告:定義了入口層的監控策略、降級觸發規則、監控頻率等。

  • 驅動層:負責XML配置檔案解析載入,RPC/元件的資源編排與執行。其中:

(1)RPC驅動層:即復仇者框架,一種自研的基於事件驅動的併發排程模型(瞭解更多,可檢視參考文獻第5點),負責解析RPC配置宣告,編排RPC資源,執行RPC呼叫。

(2)元件驅動層:負責元件配置解析,元件命中判定,元件的資源編排以及提供元件驅動入口。

  • 業務元件包:由業務邏輯元件構成的資源包,以jar形式管理。包含:標題元件、商品圖元件、到手價元件等。

此外,還有周邊生態為之賦能,包括:健康監測、輔助生態。

  • 健康監測:檢測入口層服務健康度。當指定時間視窗內錯誤率達到上限,觸發熔斷與降級。

  • 輔助生態:輔助開發人員快速構建元件應用。包含IDEA XML配置自動補全提示、maven腳手架輔助生成程式碼框架等。

整個架構是如何逐步構建起來的,構建過程中有哪些需要解決的問題,下面分模組一一介紹。

5.1 前置工作

5.1.1 統一元件口徑

首先我們要確定什麼是元件,在前文中提到:元件是一組功能相關的邏輯、資料的聚合。其中,資料可以理解為介面中的每一個欄位,邏輯即為每個欄位所對應的產品規則。為什麼把每一個欄位定義為一個元件呢?這與我們的工作職能密切相關,與中臺後端不同,平臺後端是服務於前端的後端,即:BFF(Backend For Frontend)。BFF的主要職責是組合、使用底層資料,然後按照產品規則處理展示邏輯,最後返回給前端。

日常對接中,後端根據UI要求定義介面,並根據各終端特性調整介面協議。每個UI元素對應一組產品規則,每個UI元素對應一個欄位。欄位又作為前後端資料互動的橋樑,把每個欄位劃歸為元件最合適不過。

提效新紀元-元件化開發在轉轉App中的應用-後端篇
提效新紀元-元件化開發在轉轉App中的應用-後端篇

5.1.2 推進標準化

構成元件的元素是一組標準。標準的建立有助於實現元件的複用性。前文中,我們把欄位定義為元件,欄位、元件、UI三者之間一一對應。推進元件的標準化,也就是對欄位、UI的標準化。

(1)欄位命名標準化

因為開發人員的命名習慣不一致,可能會出現多個欄位描述同一個功能點的情況。當以欄位維度劃分不同的元件後,元件會變得非常冗餘,在介面對接時也會增加溝通成本。另外,非標準化欄位對native的元件化實現不是很友好,nanative需要額外維護非標欄位資料與UI元素的對映,增加了開發與維護成本。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

(2)UI樣式標準化

雖然在不同終端、在不同頁面中UI呈現出個性化差異。但有些元素背後對應的產品邏輯是一致的。例如:商品卡片中的官方驗成色標籤傳達的內容一致,在首頁、主搜可以統一樣式。從產品角度上看,標準化的UI可以在全平臺營造統一的使用者體驗氛圍;在技術方面,不僅降低了維護API的成本,同時native根據標準化的UI可以構建出UI元件,進而豐富元件庫,提升複用性。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

5.1.3 規範介面返回值結構

介面返回值中包含著前端展示的各種資料,隨著產品的迭代,UI中的元素型別會越來越多,開發人員習慣性地不斷在介面返回值中平鋪新增的欄位。時間週期拉長,欄位數量成爆炸性增張,難以維護。因此,返回值結構也需要有一套標準,抑制欄位數量增長速度。

(1)按物件內容型別收攏欄位

以商品卡中的元素為例,頁面上有很多標籤元素:官方驗成色標籤、功能描述標籤、埋點標籤等,這些欄位在表現形式上都為純圖片或者純文字的形式,可以統一歸納為標籤物件。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

(2)按功能合併欄位

在不同的終端上,圖片連結有時要拼接屬性引數。以往針對圖片是否攜頻寬高屬性,我們會返回兩個欄位picUrl、picUrlWH,現在統一為:picUrl。是否拼接寬高引數作為元件屬性移動到元件中。

(3)融入KV結構

KV結構用來儲存一些非標欄位,如:埋點欄位postIdMap,包含上報的埋點透傳欄位。

(4)支援返回值VO擴充套件

暫時無法確認以後是否被定義為標準化欄位,先放在VO的子類VOExt中。VO中只包含標準化欄位宣告。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

5.2 元件粒度

獲取元件的執行結果經歷兩個步驟:執行RPC呼叫,然後依據產品邏輯進行資料加工。以實際使用場景為例:

渲染標題時:呼叫商品服務,獲取商品基礎資訊。

渲染到手價時:呼叫商品服務,獲取商品基礎資訊;呼叫促銷服務,獲取活動促銷資訊。

渲染劃線價時:呼叫促銷服務,獲取活動促銷資訊。

彙總RPC呼叫與資料渲染的關係,如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

RPC呼叫與資料渲染邏輯呈現多對多的關係。再次回看元件的定義,元件是一組功能相關的邏輯、資料的聚合。功能邏輯該怎樣去定義呢?若元件的功能邏輯定義為RPC呼叫與資料渲染邏輯的組合,會引發以下問題:

(1)RPC重複呼叫:多個元件中可能包含同一RPC資料來源,每個元件獲取一次RPC資料,重複呼叫,對下游造成壓力。

(2)元件職責不單一,難以複用:若合併多個元件,只呼叫一次RPC,那麼元件的職責不再單一,複用性降低。

(3)難於資源編排:元件間存在依賴關係、RPC模組間也存在依賴關係,且RPC執行順序與元件的執行順序沒有必然聯絡,當RPC與資料渲染繫結在一起時,難於資源編排。

綜上,RPC呼叫要獨立於資料渲染邏輯,元件的功能邏輯只包含資料渲染。

進一步的,當RPC呼叫從元件中分離後,需要為元件提供獲取RPC資料的方式。可以在應用上下文中提供屬性域SynchronizedMap儲存RPC結果集,為二者建立通訊橋樑。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

5.3 元件類設計

依據元件元件遵循的元件模型協議,定義元件類包含以下內容:

  • 後設資料

元件型別(componentType):標識當前元件隸屬的功能點。例如:標題元件、商品圖元件、到手價元件等等。

依賴的元件列表(dependencyComponentTypeList):標識當前元件依賴於哪些業務元件基礎資料。例如:《券資訊》資料的有無依賴於《到手價》的資料情況。

以上屬性定義在元件頂級介面中,元件頂級介面類結構如下所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇
  • 行為定義

通用行為doHandle():定義了元件的標準行為,該行為定義在元件頂級介面中。

  • 自定義元件介面

自定義行為doInnerHandle():定義了元件的自定義行為。與doHandle()的區別是:doHandle()中定義的是元件行為的通用執行邏輯,doInnerHandle()用於實現各元件的個性化業務邏輯。該行為定義在自定義元件的頂級類中,自定義元件的頂級類結構如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

基礎元件類定義好之後,還需要根據業務場景定義:定義父元件,新建業務元件。彙總類圖如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇
  • 父元件類

自定義元件的頂級類中沒有宣告具體的返回值VO型別。在實際使用時,需要依據場景宣告返回值型別,主鍵型別,引數型別等,這些內容宣告在父元件類中。比如在Feed流商品卡片場景,新建FeedComponentHandleService,指定主鍵型別為Long型別的商品infoId、指定返回值型別為FeedBaseInfoVOExt等。

  • 業務元件類

在父元件類的基礎上,可以新建業務元件類,比如:標題元件TitleV1、商品圖元件ImageV1、商品圖元件ImageV2...

5.4 引數傳遞

為了提升RPC模組、元件的複用性,在其中會增加可變引數,允許使用者在不同場景配置不同的值。RPC/元件引數值來自於介面引數,當直接使用介面請求引數作為RPC/元件的引數時,因介面請求引數屬性域 = {RPC模組引數屬性域,元件引數屬性域,其他引數},RPC/元件引數中新增了很多無用引數屬性。另一方面介面引數型別多樣,同一元件難以適配不同場景中,複用性大幅降低。所以RPC/元件應該只關注自身需要使用的引數。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

介面請求引數與RPC/元件引數獨立管理後,當外界請求到來時,需要RPC/元件建立獲取介面引數的通訊方式,RPC/元件獲取引數屬性值的過程如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

當獲取RPC/元件獲取引數屬性值時,首先獲取到RPC/元件請求的代理物件,然後由MethodInterceptor攔截代理物件的方法,轉而執行原始請求物件中的方法。

實現思路

(1)定義IRequestFiledAutoMapped介面,屬性域中含有一個ThreadLocal物件用於儲存原始請求物件。RPC/元件請求類均實現該介面。

(2)定義攔截器MethodInterceptor,用於攔截IRequestFiledAutoMapped各實現類的方法請求。

(3)定義BeanProcessor,元件Bean生成後,使用Enhancer建立代理物件。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

5.5 元件命中條件

在傳統程式設計模式中,資料渲染中包含了大量的條件判斷語句,如圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

不同的場景往往只會命中條件語句中的一個路徑。將這些條件判斷和產品功能邏輯剝離開,元件邏輯中只包含產品功能邏輯,將大幅提升元件的複用性。此外,條件的剝離可以讓功能程式碼塊瘦身,開發人員的學習、認知成本將大幅減少。

回看上圖中的示例,將條件與產品功能邏輯分離後可以劃分為3個元件:

元件1:title = title + content

元件2:title = tinyTitle

元件3:title = title + paramsValue

劃分之後,可以根據不同的場景選用不同的元件,元件邏輯更易升級維護。

元件模型中規定了組合元件的介面、規則。元件的命中條件作為規則,與元件配合使用,用來判定某個場景應該選用哪個元件。實現上,我們提供了兩種條件的宣告形式。

(1)提供一個條件頂級介面IBaseCondition,實現其中的eveluation()方法,在方法中宣告命中規則。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

(2)使用EL表示式描述命中規則,由Aviator規則引擎載入規則。

如何繫結條件與元件,以及如何執行命中條件,在5.6中將會展開描述。

5.6 管理多版本元件

  • 管理方式

各類元件準備完畢後,需要將這些元件組織起來,如何組裝元件也需要遵循一套標準。以XML檔案描述元件的裝配資訊。使用這種宣告方式,各組裝點成塊狀結構,層次清晰,以下為XML的配置樣例。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

配置檔案主要包含四部分:應用宣告、RPC模組宣告、元件宣告、自定義引數宣告。各部分宣告的內容在第5節的前置介紹中,不再贅述。

  • 載入XML

轉轉的微服務由Spring Boot框架支撐,藉助AbstractBeanDefinitionParser,重寫其中的parseInternal方法,解析XML,生成單例模式Bean。Bean的結構如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇
  • 再提元件命中條件

框架中提供了兩種元件條件接入方式:實現IBaseCondition介面或者使用EL表示式。在配置檔案中,宣告樣例如下圖。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

(1)若實現IBaseCondition介面,則完善conditionClass的屬性值,值為IBaseCondition介面實現類的類路徑。

(2)若使用EL表示式,則完善conditionEL的屬性值,值為EL表示式內容。

  • 元件命中

當條件與功能邏輯分離後,功能邏輯會演變為多個元件。因為請求場景是未知的、不確定的,將元件按照型別收攏起來為:元件組,如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

在實際場景中,不同的場景只會命中其中的唯一一個元件,是否命中元件按照如下的規則觸發:

(1)自上而下判定元件命中。命中任意元件,則完成該元件組的判定。

(2)優先讀取conditionEL配置,規則引擎執行結果返回true則命中該元件,否則不命中;如果配置了conditionClass類路徑,執行條件例項中的evaluate方法,若方法返回值為true,則命中該元件,否則不命中。

  • 元件收集

當完成某一元件組的結果判定,被命中的元件會被收集在集合中,即:Set<Class< ? extends IComponentHandleService>> 中。多個元件組的元件命中結果將匯聚在此。

5.7 元件排序

收集好元件列表之後,還不能立即執行這些元件的行為。在實際場景中,元件與元件之間存在資料依賴,如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

《券標籤》元件的展示條件依賴於《活動資訊》元件、《到手價》元件。所以在元件執行順序上,需要將《活動資訊》、《到手價》元件執行前置。底層實現上,根據元件間的依賴先後關係,排序元件。

元件之間的依賴關係可以主動宣告也可透過自動解析獲取到。排序實現上,自動解析的方式可透過三色標記的逆向解析法實現元件編排(瞭解更多,可檢視參考文獻第10點,4.3.3章節)。我們採取主動宣告依賴,有向圖拓撲編排的方式。

具體為:

(1)編寫元件時,在元件內部宣告本元件型別、依賴的元件型別。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

(2)將每個元件看作為圖的一個節點,依賴關係視為弧,生成一張有向圖,有向圖使用鄰接表儲存。

提效新紀元-元件化開發在轉轉App中的應用-後端篇
提效新紀元-元件化開發在轉轉App中的應用-後端篇

(3)對有向圖進行拓撲排序,當有向圖存在環狀結構時,日誌提示存在互相引用;若有向圖無環,則輸出最終的排序結果。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

(4)按序執行元件行為。

5.8 元件驅動

經過前述流程,元件模型構造完成。框架需要提供入口供外界呼叫。以呼叫場景中的實體數劃分場景為:單一檢視、多檢視。

  • 單一檢視:渲染單一同類實體的資料。例如:某個商品卡片,某個商品詳情頁。

  • 多檢視:渲染多個同類實體的資料。例如:多個商品卡片,多個商品詳情頁。

對於每個場景,提供相應的呼叫入口、自定義驅動元件列表的方法,如下圖所示。

提效新紀元-元件化開發在轉轉App中的應用-後端篇

單一檢視入口:renderView();多檢視入口:renderViewList()。檢視入口中提供自定義驅動元件列表的方法。例如:在多檢視場景中透過實現driveCardView()方法,實現序列執行元件或並行執行元件。

5.9 新的開發模式

使用元件化開發方式,構建feed流只需要以下幾個步驟:

(1)新建業務元件(可選):如果有新的業務邏輯,則新建業務元件類。

(2)宣告配置:在XML配置中宣告應用名、RPC模組列表、元件列表。

(3)宣告驅動:定義應用Bean、應用上下文、請求引數、元件的驅動方式等。

(4)執行驅動:執行命中的元件列表。

(5)額外的邏輯處理:埋點日誌列印等。

(6)結果返回

6 效果資料

以我的頁面增加推薦Feed場景為例:

研發側效率整體提升:2.2倍。

衡定過程:元件化模式前工時投入÷元件化模式後工時投入。即:84H÷37H≈2.2。

研發側投入成本明細如下:

提效新紀元-元件化開發在轉轉App中的應用-後端篇

7 輔助生態

  • XML自動補全外掛

編寫元件配置時,經常需要檢視元件元資訊:元件的屬性等內容,影響編寫效率。基於IntelliJ Platform Plugin Template,開發了XML自動補全提示外掛。

  • maven腳手架(規劃中)

元件開發模式,可以沉澱一套程式碼結構。腳手架生成通用程式碼後,可進一步較少開發投入。

8 總結

  • 傳統的開發模式:受版本、終端、產品迭代等多因素影響,隨著時間的推移,程式碼邏輯越來越複雜,維護成本高,複用性低,無法應對快速的產品迭代。

  • 元件化開發模式:將功能邏輯凝練為元件,程式碼更具複用性。組合元件即可完成系統的構建,高效交付。

本文詳細講述了元件化開發技術的實現過程,希望對大家有所幫助。歡迎大家在評論區留言,也可新增微訊號:zpc_1994,進一步交流。

9 參考文獻

[1] 畢偉.元件化軟體開發方法,2022,

[2] Margaret Rouse.Component-Based Development,2015,https://www.techopedia.com/definition/31002/component-based-development-cbd

[3] UNIC.Component-Based Development,2014,~itraore/seng422-06/notes/arch06-7-1.pdf

[4] 闞耀光.appview-auto-degrade-cache,2022.

[5] 陳奇恩.複雜併發場景下的併發排程模型在轉轉的演進之路,2022,https://mp.weixin.qq.com/s/6o4hQokmRytrb0Hevzly0g

[6] 陸晨,致遠,陳琦.GraphQL及後設資料驅動架構在後端BFF中的實踐,2021,https://mp.weixin.qq.com/s/mhM9tfWBlIuMVkZQ-6C0Tw

[7] Sam Newman.Backends For Frontends,2015,

[8] 谷金.通用商品卡片的設計過程,2022.

[9] 陸晨,致遠,陳琦.標準化思想及組裝式架構在後端BFF中的實踐,2022,https://mp.weixin.qq.com/s/7VlXBl9syw2ppiR3x237bA

[10] 樂彬,國樑,玉龍.美團外賣廣告平臺化的探索與實踐,2022,https://mp.weixin.qq.com/s/Iyd_uYkNI5cH2sv_VwT3NA

[11] 嚴蔚敏,吳偉民.資料結構(C語言版)[M].北京:清華大學出版社,2007.163~183.


框架作者

張鵬程、武翱、闞耀光、趙天明,均來自轉轉集團研發中心-平臺基礎體驗後端團隊。

想了解更多轉轉公司的業務實踐,歡迎點選關注下方公眾號:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027824/viewspace-2951459/,如需轉載,請註明出處,否則將追究法律責任。

相關文章