序言
在直播間開發中,隨著業務越來越復雜,以往MVC,或mvvm式的架構不太能滿足業務和技術的要求。舉例來說,如果產品想進行ABTest,對某些用戶整個下掉坐席功能,有什么樣的方法可以做到既不影響現有功能又能比較優雅的方式呢。我們在多變復雜的現實環境中,和未來不確定的因素下,又有什么樣的架構方案可以比較完美的解決這些問題,就是今天探討的組件化/變形金剛式開發。
插件/組件化是指,一個組件以一種便捷的方式在容器中添加
,移除
,查找
,配置
對應的api有 addcomponent,removecomponent,getcomponent
組件Component,一個UI或功能的比較完整的模塊。如公屏組件,顯示用戶發言,或進場的信息的模塊。
容器Container,是多個組件的集合,用于完成特定產品上的特定功能,如直播間模塊,直播間的組件有公屏組件,座位席組件,營收送禮組件,活動條組件。
好處
- 統一管理容器,通知模塊的生命周期。
比如在直播間模塊中,直播間有進入,觀看,退出直播間的事件,用戶鑒權有登錄踢出,這些事件都可以完整的通知到各個組件。
- 支持多實例,方便模塊內部的組織。
以觀看端為例上下滑動就需要支持的多個直播間并存的場景,每個直播間有相同的組件功能。
-
統一配置信息
組件需要用到一下共同的數據,或配置共同的數據,如uid,roomId,roomName
實現步驟
由于涉及到保密性,這里不貼代碼,用純文字或偽代碼的形式講述大致過程。
- livingRoomImpl 和 ILivingRoom 對應直播間模塊的聲明和實現,
I
開頭一般表示protocol,里面的實現
@protocol 組件管理
-(void)添加組件;
-(void)移除組件;
-(id)根據名字找到組件;
-(void)移除所有的組件;
@end
- 組件的共同代理
@protocol 組件的代理
-(instancetype)初始化組件;
-(void)開始添加組件;
-(void)準備移除組件;
-(void)房間號變化;
-(void)用戶被踢出;
-(void)用戶信息變更;
@end
- 組件的共同事件
@protocol 組件信息
-(id)appid
-(id)房間號
-(id)用戶id
-(id)房間信息
-(api)組件的api
@end
- 各自組件的protocol
如公屏的
@protocol 公屏的protocol
-(bool)發送公屏
@end
另外有營收,坐席等其他組件類似。
注意的點
1.根據protocol找到實例
有一個大前提是需要根據protocol找到對應的實例。
介紹一個比較簡單的方法,根據protocol的名字和直播間id把當前實例保存到數據中心,下次需要取得實例的時候就直接取得該實例。GetComponentByProtocol(protocol)
-
隱藏實現類細節。僅僅公開出protocol
有個技巧是使用c函數去創建實例和完成組裝如
RegisterPublicScreenComponent()
直播間配置相關的東西最好在初始化的時候,默認加載。注意初始化之前不要使用模塊的方法,這個可以在設計上考慮怎么避免
使用方式
有了之前的基礎,假設我們已經有了直播,公屏,坐席,送禮這些模塊,現在需要把他們組裝起來了。
于是有了以下的代碼
[ATH_MIDWARE(ILivingRoom) createLivingRoom]
RegisterVideoComponent()
RegisterPublicScreenComponent()
RegisterSeatMembersCompnent()
RegisterSendGiftComponent()
需要把一個模塊去掉,注釋掉那個Register即可
如果我們把RegisterVideoComponent
注釋,就變成了文字直播間了,也同樣支持送禮等功能。
后續
推行組件化其實是一個很痛苦的事情,面臨著解耦和執行兩個大問題。
解耦是需要分離出職責,找到組件核心的功能,實現并且對外聲明必要的api
執行,前提需要理解整個組件化的核心思想,其中的溝通必不可少。如何定位和防止/提示問題也是考驗架構師的能力。
寥寥數語,未能盡興?有對架構有興趣的同學可以添加我微信一起聊 haugnbo