自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

提效新紀元-組件化開發(fā)在轉(zhuǎn)轉(zhuǎn)App中的應(yīng)用-后端篇

開發(fā) 前端
本文詳細講述了組件化開發(fā)技術(shù)的實現(xiàn)過程,希望對大家有所幫助。歡迎大家在評論區(qū)留言,也可添加微信號:??zpc_1994??,進一步交流。

1 前言

組件化開發(fā)是一種利用可重用的軟件構(gòu)件來設(shè)計和開發(fā)計算機系統(tǒng)的過程。借助組件化開發(fā)可以實現(xiàn)最小化、高效交付。

平臺基礎(chǔ)體驗部將業(yè)務(wù)邏輯抽象為組件,通過組合組件快速構(gòu)建商品Feed流,研發(fā)效率整體提升2倍。組件化開發(fā)不僅帶來效率的提升,同時極大地增加了代碼復(fù)用性、降低了系統(tǒng)的復(fù)雜性等等。本文將詳細介紹組件化開發(fā)的落地過程,為大家揭曉轉(zhuǎn)轉(zhuǎn)App快速迭代的奧秘。

2 背景

平臺基礎(chǔ)體驗部主要承接轉(zhuǎn)轉(zhuǎn)App、小程序迭代。

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

2022年3月,我們著手策劃新方案,并構(gòu)建出一套組件化開發(fā)流程。

2022年9月底,距離轉(zhuǎn)轉(zhuǎn)集團宣布品牌升級還有一個月的時間,App、小程序需要整體換新,其中僅Feed功能點,升級多達20幾處。組件化開發(fā)借此契機,開始大范圍應(yīng)用,效果得到了印證。

圖片

圖1 Feed改版UI示例

3 現(xiàn)狀分析

3.1 對接流程與開發(fā)流程

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

圖片

圖2 對接流程

開發(fā)同學小張,根據(jù)App首頁UI圖例定字段后,同步給native以及QA。隨后著手另一功能點:App收藏夾推薦,定字段、同步字段。

接口評審后,進入開發(fā),開發(fā)流程如下圖所示。

圖片

圖3 開發(fā)流程

RD小張開發(fā)首頁時,首先獲取各業(yè)務(wù)的RPC數(shù)據(jù),然后自上而下寫好數(shù)據(jù)渲染邏輯。完成自測后,提供給native、QA測試環(huán)境。緊接著,投入到收藏夾功能點開發(fā),流程類似。

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

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

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

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

圖片

圖4 對接流程中的小插曲

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

圖片

圖5 開發(fā)流程中的小插曲

3.2 項目進展

進入開發(fā)前,RD基于現(xiàn)有的改動點做出技術(shù)評估,輸出排期。以App首頁、App收藏夾推薦為例,從產(chǎn)品規(guī)則上看,只有RPC數(shù)據(jù)源不同,RD認為大部分邏輯是可以復(fù)用的。所以,功能相近的位置可能會適當?shù)臏p少排期。

但實際開發(fā)中,新的代碼邏輯與歷史邏輯存在沖突,無法順利的融入到數(shù)據(jù)渲染代碼塊。各接口的實體類定義五花八門,復(fù)用某些數(shù)據(jù)渲染方法時,存在很多實體之間的數(shù)據(jù)轉(zhuǎn)換,代碼顯得十分臃腫。很多無法預(yù)知的“小插曲”導致原本答應(yīng)產(chǎn)品在10個工作日內(nèi)完成20個Feed改造,即使加班也無法按時交付。其他職能的進度也會受到影響,給整個項目帶來風險。

圖片

圖6 項目進展

3.3 問題匯總

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

  • 版本、終端、UI差異增加了代碼的復(fù)雜性,難以復(fù)用:RD為了適配各端不同的樣式,或者兼容native產(chǎn)生的線上問題,或者為了兼容不同版本的樣式,往往要寫很多控制邏輯,使得代碼邏輯越來越臃腫,復(fù)雜性與維護成本逐漸增加。
  • 接口返回值字段不統(tǒng)一:因為開發(fā)人員的命名習慣不一致,隨著接口的增多、產(chǎn)品的不斷迭代,可能會出現(xiàn)多個字段描述同一個功能點的情況。接口字段數(shù)量成爆炸式增長,難以維護。出現(xiàn)問題時,RD很難快速定位字段,溝通成本、認知成本也會大幅增加。
  • 無法適應(yīng)產(chǎn)品快速迭代:AB方案的加入、產(chǎn)品邏輯的調(diào)整使得元素的渲染邏輯過于龐大,元素之間的依賴關(guān)系變得更加復(fù)雜,RD無法快速交付。
  • 工作內(nèi)容重復(fù),排期長,易引入延期風險:很多功能點十分相似,但是開發(fā)中無法完美復(fù)用,使得排期較長。過長的排期外加無法預(yù)知的隱藏問題,很有可能帶來延期風險。

3.4 問題切入點與解決方案

  • 切入點

(1)RPC模塊、數(shù)據(jù)渲染邏輯中,有些內(nèi)容完全一致,如果將他們劃分為模塊,將大幅增加代碼的復(fù)用性。

(2)數(shù)據(jù)渲染數(shù)據(jù)是過程化的、自上而下的,如果能夠打破這種串行開發(fā)模式,各數(shù)據(jù)渲染邏輯之間的耦合性大幅降低。

圖片

圖7 流程分析圖示-1

(3)深入觀察單一數(shù)據(jù)渲染內(nèi)部,如果將版本兼容、終端差異、AB實驗等從數(shù)據(jù)渲染邏輯中剝離,只留下核心邏輯,數(shù)據(jù)模渲染更具復(fù)用性。

(4)不同元素的數(shù)據(jù)渲染邏輯之間難免會存在依賴關(guān)系,需要有一種資源編排機制,能夠?qū)⒏鲾?shù)據(jù)渲染邏輯按規(guī)則組織起來。

圖片

圖8 流程分析圖示-2

  • 解決方案

結(jié)合相關(guān)的技術(shù)調(diào)研以及業(yè)界相關(guān)的經(jīng)驗,我們引入了《組件化開發(fā)》,即:基于組件的開發(fā)。組件、組件化開發(fā)帶來的優(yōu)勢能夠達成我們的訴求,組件、組件化開發(fā)具體是什么,具有什么優(yōu)勢?接下來將具體展開描述。

4 走進組件化開發(fā)

4.1 組件定義

組件是一組功能相關(guān)的邏輯、數(shù)據(jù)的聚合。

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

4.2 組件分類

  • 按職能可將組件分為:技術(shù)組件和業(yè)務(wù)組件。業(yè)務(wù)組件是把一組相關(guān)的業(yè)務(wù)邏輯封裝為一個組件,也稱為管理邏輯組件。
  • 按層次可以分為:框架組件、平臺組件、通用管理邏輯組件、領(lǐng)域管理邏輯組件、行業(yè)管理邏輯組件、個性化管理邏輯組件等。
  • 按來源可以分為:開源組件、商業(yè)組件、自研組件等。

4.3 組件模型

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

圖片

圖9 組件模型的基礎(chǔ)元素

組件模型包括:接口列表、命名、元數(shù)據(jù)、互通性、自定義組件接口、組合接口、組件演進、打包與部署。

4.4 組件特點

一個設(shè)計良好的組件應(yīng)該具備如下幾個特點:

  • 可管理:組件是基于統(tǒng)一的模型進行設(shè)計和實現(xiàn),遵循統(tǒng)一的技術(shù)規(guī)范,由統(tǒng)一的元數(shù)據(jù)進行描述,有清晰的分類和分層,可由組件工具進行統(tǒng)一管理,以規(guī)范一致的模式進行使用。
  • 可復(fù)用:可復(fù)用是組件的一個核心特點。通常組件都是經(jīng)過良好的設(shè)計和封裝的,可以被多個場景復(fù)用。只有能夠復(fù)用,才能更好地發(fā)揮組件的價值。
  • 可配置:為了更好地復(fù)用,組件在不同的場景下使用時不需要去修改組件自身,通常組件需要把不同場景下可能會變化的部分作為可變參數(shù),允許使用者通過配置不同的值,來滿足不同使用場景下的需求,使組件具有更好的可復(fù)用性??膳渲玫膬?nèi)容通常包括環(huán)境信息、參數(shù)、規(guī)則、模型屬性等。
  • 可擴展:在使用組件的過程中,當通過配置也無法滿足場景化的使用需求時,組件的可擴展性就變得尤其重要,如果一個組件不具備可擴展性,將極大降低組件的復(fù)用價值。組件的擴展性通??梢酝ㄟ^良好的設(shè)計來實現(xiàn),如支持繼承,可局部邏輯重寫;支持事件,通過前置后置事件,允許使用定制規(guī)則和邏輯,就可以更好地滿足不同場景下的個性化使用需求,提高組件的可復(fù)用性,發(fā)揮出組件更大的價值。

4.5 組件化開發(fā)

組件化開發(fā): 組件化開發(fā),即:基于組件的開發(fā)(Component-Based Development,簡稱:CBD),是一種利用可重用的軟件構(gòu)件(組件)來設(shè)計和開發(fā)計算機系統(tǒng)的過程。

組件化開發(fā)的起源: 組件化開發(fā)出現(xiàn)于20世紀90年代末。當時面向?qū)ο蠼i_發(fā)(Object-Oriented,簡稱:OO)沒有像最初建議的那樣被廣泛的重用。OO產(chǎn)生了大量細粒度的類、對象和關(guān)系,在這些較小的單元中發(fā)現(xiàn)可重用的部件是非常困難的。CBD背后的思想是集成相關(guān)的部分并對它們進行集體重用。

4.6 組件化開發(fā)的類型

組件化開發(fā)分為兩類:機會式重用、帶有開發(fā)量的重用。

  • 機會式重用:根據(jù)已有的組件組合成一套系統(tǒng)。

圖片

圖10 機會式重用

  • 帶有開發(fā)量的重用:根據(jù)需求,定制開發(fā)某些組件,然后將組件組合成一套系統(tǒng)。

圖片

圖11 帶有開發(fā)量的重用

在日常的使用場景中,因為產(chǎn)品不斷地迭代,使用現(xiàn)有組件直接組合成系統(tǒng)的場景較少,帶有開發(fā)量的組件重用應(yīng)用場景更為廣泛。

4.7 組件化開發(fā)的優(yōu)勢

  • 最小化交付:基于現(xiàn)有的組件,即可裝配成系統(tǒng)。
  • 高效:開發(fā)人員可以更集中關(guān)注需求變更點,快速完成產(chǎn)品升級。
  • 提升系統(tǒng)質(zhì)量:開發(fā)人員可以有更多的時間來確保系統(tǒng)質(zhì)量。組件的高質(zhì)量決定了系統(tǒng)的質(zhì)量。
  • 減少支出:減少資源投入。

5 組件化開發(fā)的落地過程

借助組件化開發(fā)思想,我們構(gòu)建了一套組件化開發(fā)架構(gòu),內(nèi)部稱之為:星環(huán),整體架構(gòu)如下圖所示。

圖片

圖12 星環(huán)框架-組件化開發(fā)整體架構(gòu)圖

星環(huán)體系可以總結(jié)為兩層一包:聲明層、驅(qū)動層以及業(yè)務(wù)組件包。

  • 聲明層:包含基礎(chǔ)聲明、RPC模塊聲明、組件聲明、降級觸發(fā)規(guī)則聲明?;A(chǔ)聲明以Java代碼形式聲明,剩余部分以XML形式聲明。

(1)基礎(chǔ)聲明:定義了應(yīng)用名、應(yīng)用上下文、請求參數(shù)、組件的驅(qū)動方式等。

(2)RPC模塊聲明:定義了應(yīng)用中包含哪些RPC引用,RPC模塊之間的依賴關(guān)系。

(3)組件聲明:定義了應(yīng)用中包含哪些業(yè)務(wù)組件、組件的屬性、組件的觸發(fā)條件。

(4)降級觸發(fā)規(guī)則聲明:定義了入口層的監(jiān)控策略、降級觸發(fā)規(guī)則、監(jiān)控頻率等。

  • 驅(qū)動層:負責XML配置文件解析加載,RPC/組件的資源編排與執(zhí)行。其中:

(1)RPC驅(qū)動層:即復(fù)仇者框架,一種自研的基于事件驅(qū)動的并發(fā)調(diào)度模型(了解更多,可查看參考文獻第5點),負責解析RPC配置聲明,編排RPC資源,執(zhí)行RPC調(diào)用。

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

  • 業(yè)務(wù)組件包:由業(yè)務(wù)邏輯組件構(gòu)成的資源包,以jar形式管理。包含:標題組件、商品圖組件、到手價組件等。

此外,還有周邊生態(tài)為之賦能,包括:健康監(jiān)測、輔助生態(tài)。

  • 健康監(jiān)測:檢測入口層服務(wù)健康度。當指定時間窗口內(nèi)錯誤率達到上限,觸發(fā)熔斷與降級。
  • 輔助生態(tài):輔助開發(fā)人員快速構(gòu)建組件應(yīng)用。包含IDEA XML配置自動補全提示、maven腳手架輔助生成代碼框架等。

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

5.1 前置工作

5.1.1 統(tǒng)一組件口徑

首先我們要確定什么是組件,在前文中提到:組件是一組功能相關(guān)的邏輯、數(shù)據(jù)的聚合。其中,數(shù)據(jù)可以理解為接口中的每一個字段,邏輯即為每個字段所對應(yīng)的產(chǎn)品規(guī)則。為什么把每一個字段定義為一個組件呢?這與我們的工作職能密切相關(guān),與中臺后端不同,平臺后端是服務(wù)于前端的后端,即:BFF(Backend For Frontend)。BFF的主要職責是組合、使用底層數(shù)據(jù),然后按照產(chǎn)品規(guī)則處理展示邏輯,最后返回給前端。

日常對接中,后端根據(jù)UI要求定義接口,并根據(jù)各終端特性調(diào)整接口協(xié)議。每個UI元素對應(yīng)一組產(chǎn)品規(guī)則,每個UI元素對應(yīng)一個字段。字段又作為前后端數(shù)據(jù)交互的橋梁,把每個字段劃歸為組件最合適不過。

圖片

圖13 日常對接流程

圖片

圖14 BFF開發(fā)模式

5.1.2 推進標準化

構(gòu)成組件的元素是一組標準。標準的建立有助于實現(xiàn)組件的復(fù)用性。前文中,我們把字段定義為組件,字段、組件、UI三者之間一一對應(yīng)。推進組件的標準化,也就是對字段、UI的標準化。

(1)字段命名標準化

因為開發(fā)人員的命名習慣不一致,可能會出現(xiàn)多個字段描述同一個功能點的情況。當以字段維度劃分不同的組件后,組件會變得非常冗余,在接口對接時也會增加溝通成本。另外,非標準化字段對native的組件化實現(xiàn)不是很友好,nanative需要額外維護非標字段數(shù)據(jù)與UI元素的映射,增加了開發(fā)與維護成本。

圖片

圖15 native組件化方案

(2)UI樣式標準化

雖然在不同終端、在不同頁面中UI呈現(xiàn)出個性化差異。但有些元素背后對應(yīng)的產(chǎn)品邏輯是一致的。例如:商品卡片中的官方驗成色標簽傳達的內(nèi)容一致,在首頁、主搜可以統(tǒng)一樣式。從產(chǎn)品角度上看,標準化的UI可以在全平臺營造統(tǒng)一的用戶體驗氛圍;在技術(shù)方面,不僅降低了維護API的成本,同時native根據(jù)標準化的UI可以構(gòu)建出UI組件,進而豐富組件庫,提升復(fù)用性。

圖片

圖16 不同F(xiàn)eed的共同元素

5.1.3 規(guī)范接口返回值結(jié)構(gòu)

接口返回值中包含著前端展示的各種數(shù)據(jù),隨著產(chǎn)品的迭代,UI中的元素類型會越來越多,開發(fā)人員習慣性地不斷在接口返回值中平鋪新增的字段。時間周期拉長,字段數(shù)量成爆炸性增張,難以維護。因此,返回值結(jié)構(gòu)也需要有一套標準,抑制字段數(shù)量增長速度。

(1)按對象內(nèi)容類型收攏字段

以商品卡中的元素為例,頁面上有很多標簽元素:官方驗成色標簽、功能描述標簽、埋點標簽等,這些字段在表現(xiàn)形式上都為純圖片或者純文字的形式,可以統(tǒng)一歸納為標簽對象。

圖片

圖17 按對象內(nèi)容類型收攏字段

(2)按功能合并字段

在不同的終端上,圖片鏈接有時要拼接屬性參數(shù)。以往針對圖片是否攜帶寬高屬性,我們會返回兩個字段picUrl、picUrlWH,現(xiàn)在統(tǒng)一為:picUrl。是否拼接寬高參數(shù)作為組件屬性移動到組件中。

(3)融入KV結(jié)構(gòu)

KV結(jié)構(gòu)用來存儲一些非標字段,如:埋點字段postIdMap,包含上報的埋點透傳字段。

(4)支持返回值VO擴展

暫時無法確認以后是否被定義為標準化字段,先放在VO的子類VOExt中。VO中只包含標準化字段聲明。

圖片

圖18 返回值VO類圖

5.2 組件粒度

獲取組件的執(zhí)行結(jié)果經(jīng)歷兩個步驟:執(zhí)行RPC調(diào)用,然后依據(jù)產(chǎn)品邏輯進行數(shù)據(jù)加工。以實際使用場景為例:

渲染標題時:調(diào)用商品服務(wù),獲取商品基礎(chǔ)信息。

渲染到手價時:調(diào)用商品服務(wù),獲取商品基礎(chǔ)信息;調(diào)用促銷服務(wù),獲取活動促銷信息。

渲染劃線價時:調(diào)用促銷服務(wù),獲取活動促銷信息。

匯總RPC調(diào)用與數(shù)據(jù)渲染的關(guān)系,如下圖所示。

圖片

圖19 RPC調(diào)用與數(shù)據(jù)渲染邏輯關(guān)系圖

RPC調(diào)用與數(shù)據(jù)渲染邏輯呈現(xiàn)多對多的關(guān)系。再次回看組件的定義,組件是一組功能相關(guān)的邏輯、數(shù)據(jù)的聚合。功能邏輯該怎樣去定義呢?若組件的功能邏輯定義為RPC調(diào)用與數(shù)據(jù)渲染邏輯的組合,會引發(fā)以下問題:

(1)RPC重復(fù)調(diào)用:多個組件中可能包含同一RPC數(shù)據(jù)源,每個組件獲取一次RPC數(shù)據(jù),重復(fù)調(diào)用,對下游造成壓力。

(2)組件職責不單一,難以復(fù)用:若合并多個組件,只調(diào)用一次RPC,那么組件的職責不再單一,復(fù)用性降低。

(3)難于資源編排:組件間存在依賴關(guān)系、RPC模塊間也存在依賴關(guān)系,且RPC執(zhí)行順序與組件的執(zhí)行順序沒有必然聯(lián)系,當RPC與數(shù)據(jù)渲染綁定在一起時,難于資源編排。

綜上,RPC調(diào)用要獨立于數(shù)據(jù)渲染邏輯,組件的功能邏輯只包含數(shù)據(jù)渲染。

進一步的,當RPC調(diào)用從組件中分離后,需要為組件提供獲取RPC數(shù)據(jù)的方式??梢栽趹?yīng)用上下文中提供屬性域SynchronizedMap存儲RPC結(jié)果集,為二者建立通信橋梁。

圖片

圖20 RPC/數(shù)據(jù)渲染間的數(shù)據(jù)交互

5.3 組件類設(shè)計

依據(jù)組件組件遵循的組件模型協(xié)議,定義組件類包含以下內(nèi)容:

  • 元數(shù)據(jù)

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

依賴的組件列表(dependencyComponentTypeList):標識當前組件依賴于哪些業(yè)務(wù)組件基礎(chǔ)數(shù)據(jù)。例如:《券信息》數(shù)據(jù)的有無依賴于《到手價》的數(shù)據(jù)情況。

以上屬性定義在組件頂級接口中,組件頂級接口類結(jié)構(gòu)如下所示。

圖片

圖21 組件頂級接口

  • 行為定義

通用行為doHandle():定義了組件的標準行為,該行為定義在組件頂級接口中。

  • 自定義組件接口

自定義行為doInnerHandle():定義了組件的自定義行為。與doHandle()的區(qū)別是:doHandle()中定義的是組件行為的通用執(zhí)行邏輯,doInnerHandle()用于實現(xiàn)各組件的個性化業(yè)務(wù)邏輯。該行為定義在自定義組件的頂級類中,自定義組件的頂級類結(jié)構(gòu)如下圖所示。

圖片

圖22 自定義組件的頂級類

基礎(chǔ)組件類定義好之后,還需要根據(jù)業(yè)務(wù)場景定義:定義父組件,新建業(yè)務(wù)組件。匯總類圖如下圖所示。

圖片

圖23 組件類圖

  • 父組件類

自定義組件的頂級類中沒有聲明具體的返回值VO類型。在實際使用時,需要依據(jù)場景聲明返回值類型,主鍵類型,參數(shù)類型等,這些內(nèi)容聲明在父組件類中。比如在Feed流商品卡片場景,新建FeedComponentHandleService,指定主鍵類型為Long類型的商品infoId、指定返回值類型為FeedBaseInfoVOExt等。

  • 業(yè)務(wù)組件類

在父組件類的基礎(chǔ)上,可以新建業(yè)務(wù)組件類,比如:標題組件TitleV1、商品圖組件ImageV1、商品圖組件ImageV2...

5.4 參數(shù)傳遞

為了提升RPC模塊、組件的復(fù)用性,在其中會增加可變參數(shù),允許使用者在不同場景配置不同的值。RPC/組件參數(shù)值來自于接口參數(shù),當直接使用接口請求參數(shù)作為RPC/組件的參數(shù)時,因接口請求參數(shù)屬性域 = {RPC模塊參數(shù)屬性域,組件參數(shù)屬性域,其他參數(shù)},RPC/組件參數(shù)中新增了很多無用參數(shù)屬性。另一方面接口參數(shù)類型多樣,同一組件難以適配不同場景中,復(fù)用性大幅降低。所以RPC/組件應(yīng)該只關(guān)注自身需要使用的參數(shù)。

圖片

圖24 參數(shù)設(shè)置

接口請求參數(shù)與RPC/組件參數(shù)獨立管理后,當外界請求到來時,需要RPC/組件建立獲取接口參數(shù)的通信方式,RPC/組件獲取參數(shù)屬性值的過程如下圖所示。

圖片

圖25 獲取RPC/組件參數(shù)屬性值的過程

當獲取RPC/組件獲取參數(shù)屬性值時,首先獲取到RPC/組件請求的代理對象,然后由MethodInterceptor攔截代理對象的方法,轉(zhuǎn)而執(zhí)行原始請求對象中的方法。

實現(xiàn)思路:

(1)定義IRequestFiledAutoMapped接口,屬性域中含有一個ThreadLocal對象用于存儲原始請求對象。RPC/組件請求類均實現(xiàn)該接口。

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

(3)定義BeanProcessor,組件Bean生成后,使用Enhancer創(chuàng)建代理對象。

圖片

圖26 請求參數(shù)、自動映射處理類圖

5.5 組件命中條件

在傳統(tǒng)編程模式中,數(shù)據(jù)渲染中包含了大量的條件判斷語句,如圖所示。

圖片

圖27 耦合條件判斷的數(shù)據(jù)渲染代碼

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

回看上圖中的示例,將條件與產(chǎn)品功能邏輯分離后可以劃分為3個組件:

組件1:title = title + content

組件2:title = tinyTitle

組件3:title = title + paramsValue

劃分之后,可以根據(jù)不同的場景選用不同的組件,組件邏輯更易升級維護。

組件模型中規(guī)定了組合組件的接口、規(guī)則。組件的命中條件作為規(guī)則,與組件配合使用,用來判定某個場景應(yīng)該選用哪個組件。實現(xiàn)上,我們提供了兩種條件的聲明形式。

(1)提供一個條件頂級接口IBaseCondition,實現(xiàn)其中的eveluation()方法,在方法中聲明命中規(guī)則。

圖片

圖28 條件頂級接口

(2)使用EL表達式描述命中規(guī)則,由Aviator規(guī)則引擎加載規(guī)則。

如何綁定條件與組件,以及如何執(zhí)行命中條件,在5.6中將會展開描述。

5.6 管理多版本組件

  • 管理方式

各類組件準備完畢后,需要將這些組件組織起來,如何組裝組件也需要遵循一套標準。以XML文件描述組件的裝配信息。使用這種聲明方式,各組裝點成塊狀結(jié)構(gòu),層次清晰,以下為XML的配置樣例。

圖片

圖29 demoApp1的組件配置樣例

配置文件主要包含四部分:應(yīng)用聲明、RPC模塊聲明、組件聲明、自定義參數(shù)聲明。各部分聲明的內(nèi)容在第5節(jié)的前置介紹中,不再贅述。

  • 加載XML

轉(zhuǎn)轉(zhuǎn)的微服務(wù)由Spring Boot框架支撐,借助AbstractBeanDefinitionParser,重寫其中的parseInternal方法,解析XML,生成單例模式Bean。Bean的結(jié)構(gòu)如下圖所示。

圖片

圖30 星環(huán)組件Bean結(jié)構(gòu)

  • 再提組件命中條件

框架中提供了兩種組件條件接入方式:實現(xiàn)IBaseCondition接口或者使用EL表達式。在配置文件中,聲明樣例如下圖。

圖片

圖31 組件命中規(guī)則聲明示例

(1)若實現(xiàn)IBaseCondition接口,則完善conditionClass的屬性值,值為IBaseCondition接口實現(xiàn)類的類路徑。

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

  • 組件命中

當條件與功能邏輯分離后,功能邏輯會演變?yōu)槎鄠€組件。因為請求場景是未知的、不確定的,將組件按照類型收攏起來為:組件組,如下圖所示。

圖片

圖32 組件組配置結(jié)構(gòu)

在實際場景中,不同的場景只會命中其中的唯一一個組件,是否命中組件按照如下的規(guī)則觸發(fā):

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

(2)優(yōu)先讀取conditionEL配置,規(guī)則引擎執(zhí)行結(jié)果返回true則命中該組件,否則不命中;如果配置了conditionClass類路徑,執(zhí)行條件實例中的evaluate方法,若方法返回值為true,則命中該組件,否則不命中。

  • 組件收集

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

5.7 組件排序

收集好組件列表之后,還不能立即執(zhí)行這些組件的行為。在實際場景中,組件與組件之間存在數(shù)據(jù)依賴,如下圖所示。

圖片

圖33 組件之間的依賴

《券標簽》組件的展示條件依賴于《活動信息》組件、《到手價》組件。所以在組件執(zhí)行順序上,需要將《活動信息》、《到手價》組件執(zhí)行前置。底層實現(xiàn)上,根據(jù)組件間的依賴先后關(guān)系,排序組件。

組件之間的依賴關(guān)系可以主動聲明也可通過自動解析獲取到。排序?qū)崿F(xiàn)上,自動解析的方式可通過三色標記的逆向解析法實現(xiàn)組件編排(了解更多,可查看參考文獻第10點,4.3.3章節(jié))。我們采取主動聲明依賴,有向圖拓撲編排的方式。

具體為:

(1)編寫組件時,在組件內(nèi)部聲明本組件類型、依賴的組件類型。

圖片

圖34 聲明本組件類型、依賴的組件類型

(2)將每個組件看作為圖的一個節(jié)點,依賴關(guān)系視為弧,生成一張有向圖,有向圖使用鄰接表存儲。

圖片

圖35 組件節(jié)點有向圖

圖片

圖36 組件節(jié)點鄰接表

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

圖片

圖37 組件節(jié)點拓撲排序

(4)按序執(zhí)行組件行為。

5.8 組件驅(qū)動

經(jīng)過前述流程,組件模型構(gòu)造完成??蚣苄枰峁┤肟诠┩饨缯{(diào)用。以調(diào)用場景中的實體數(shù)劃分場景為:單一視圖、多視圖。

  • 單一視圖:渲染單一同類實體的數(shù)據(jù)。例如:某個商品卡片,某個商品詳情頁。
  • 多視圖:渲染多個同類實體的數(shù)據(jù)。例如:多個商品卡片,多個商品詳情頁。

對于每個場景,提供相應(yīng)的調(diào)用入口、自定義驅(qū)動組件列表的方法,如下圖所示。

圖片

圖38 組件調(diào)用入口類

單一視圖入口:renderView();多視圖入口:renderViewList()。視圖入口中提供自定義驅(qū)動組件列表的方法。例如:在多視圖場景中通過實現(xiàn)driveCardView()方法,實現(xiàn)串行執(zhí)行組件或并行執(zhí)行組件。

5.9 新的開發(fā)模式

使用組件化開發(fā)方式,構(gòu)建feed流只需要以下幾個步驟:

(1)新建業(yè)務(wù)組件(可選):如果有新的業(yè)務(wù)邏輯,則新建業(yè)務(wù)組件類。

(2)聲明配置:在XML配置中聲明應(yīng)用名、RPC模塊列表、組件列表。

(3)聲明驅(qū)動:定義應(yīng)用Bean、應(yīng)用上下文、請求參數(shù)、組件的驅(qū)動方式等。

(4)執(zhí)行驅(qū)動:執(zhí)行命中的組件列表。

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

(6)結(jié)果返回

6 效果數(shù)據(jù)

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

研發(fā)側(cè)效率整體提升:2.2倍。

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

研發(fā)側(cè)投入成本明細如下:

圖片

圖39 研發(fā)效率明細

7 輔助生態(tài)

  • XML自動補全插件

編寫組件配置時,經(jīng)常需要查看組件元信息:組件的屬性等內(nèi)容,影響編寫效率?;贗ntelliJ Platform Plugin Template,開發(fā)了XML自動補全提示插件。

  • maven腳手架(規(guī)劃中)

組件開發(fā)模式,可以沉淀一套代碼結(jié)構(gòu)。腳手架生成通用代碼后,可進一步較少開發(fā)投入。

8 總結(jié)

  • 傳統(tǒng)的開發(fā)模式:受版本、終端、產(chǎn)品迭代等多因素影響,隨著時間的推移,代碼邏輯越來越復(fù)雜,維護成本高,復(fù)用性低,無法應(yīng)對快速的產(chǎn)品迭代。
  • 組件化開發(fā)模式:將功能邏輯凝練為組件,代碼更具復(fù)用性。組合組件即可完成系統(tǒng)的構(gòu)建,高效交付。

本文詳細講述了組件化開發(fā)技術(shù)的實現(xiàn)過程,希望對大家有所幫助。歡迎大家在評論區(qū)留言,也可添加微信號:zpc_1994,進一步交流。

9 參考文獻

[1] 畢偉.組件化軟件開發(fā)方法,2022,http://mm.chinapower.com.cn/zjqy/gddh/20221207/178571.html

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

[3] UNIC.Component-Based Development,2014,https://www.ece.uvic.ca/~itraore/seng422-06/notes/arch06-7-1.pdf

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

[5] 陳奇恩.復(fù)雜并發(fā)場景下的并發(fā)調(diào)度模型在轉(zhuǎn)轉(zhuǎn)的演進之路,2022,https://mp.weixin.qq.com/s/6o4hQokmRytrb0Hevzly0g

[6] 陸晨,致遠,陳琦.GraphQL及元數(shù)據(jù)驅(qū)動架構(gòu)在后端BFF中的實踐,2021,https://mp.weixin.qq.com/s/mhM9tfWBlIuMVkZQ-6C0Tw

[7] Sam Newman.Backends For Frontends,2015,https://samnewman.io/patterns/architectural/bff/

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

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

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

[11] 嚴蔚敏,吳偉民.數(shù)據(jù)結(jié)構(gòu)(C語言版)[M].北京:清華大學出版社,2007.163~183.

責任編輯:武曉燕 來源: 轉(zhuǎn)轉(zhuǎn)技術(shù)
相關(guān)推薦

2022-10-20 08:34:09

圖像算法商品

2021-02-27 10:58:25

基礎(chǔ)組件React

2021-02-26 14:35:23

開發(fā)技能代碼

2015-01-06 10:01:17

iPhone 6移動支付

2013-03-05 18:01:20

CompuwaredynaTraceAPM

2013-01-07 14:06:07

2022-07-08 11:18:33

前端實踐自動化

2009-08-20 10:10:16

敏捷開發(fā)支付寶

2025-04-03 04:21:00

SLM語言模型

2012-08-01 15:05:47

IBM

2024-07-11 11:31:17

2010-03-09 11:40:30

IBM智慧建筑

2024-05-21 12:13:12

2024-08-06 10:25:20

2012-12-04 15:47:45

2009-04-01 10:46:00

2014-11-07 17:29:04

2019-08-15 09:00:00

AI人工智能

2014-10-08 16:41:08

GITC2014全球互聯(lián)網(wǎng)技術(shù)大會
點贊
收藏

51CTO技術(shù)棧公眾號