當一個App只有幾個人開發的時候,很容易就會在一個單項目中開發。但當App開發人數越來越多,甚至幾百人,十幾個不同BU都在協調開發同一個App的時候,就必須對架構進行組件化,才能方便開發。本文主要基于手機淘寶的一次架構探索:手機淘寶客戶端架構探索實踐,基于此文進行的一些學習和探索,寫一篇文章給自己梳理一下。
首先,第一個問題,為何需要組件化? 如果依舊是單工程項目,或者是多工程引入同一個項目的開發,會有以下的問題: 1. 嚴重的代碼耦合 比如a模塊要跳轉b模塊的頁面,就要在a模塊的代碼中耦合b模塊的頁面代碼 2. 協同工作困難 開發工程中需要去編譯別的模塊的代碼,還容易出現沖突問題,引發別的問題 3. 測試效率低下 不僅測試某一個功能可能需要耦合別的模塊代碼,做回歸測試的時候業務也太多時分麻煩 4. 發布不夠靈活 出現問題定位麻煩,線上熱更新也困難
為了解決這些問題,所以需要重構代碼,達到組件化的目的。
手機淘寶組件化兩大核心: 1. 分而治之 2. 一些皆組件
拿一張PPT里的圖:

可以看到,手機淘寶將業務都進行細粒度的拆分,拆分出的每一個部分都作為一個組件。每個組件可以單獨進行測試與調試,并且確保了單一的功能性,方便在新業務接入的時候,可以按照需求選擇相應的組件來進行添加。

對于bundle如何組合,這里用的是CocoaPods。
CocoaPods是一個著名的iOS類庫管理工具。這里就不詳細介紹如何安裝與用CocoaPods了,感興趣的可以自己去CocoaPods Guide去看一下。 通過CocoaPods可以十分方便的選擇需要的bundle包進入項目,并且最關鍵的是可以控制bundle包的版本號,選擇穩定的舊版本或者新功能的老版本,避免了協同開發的時候,可能出現的外部問題,方便開發與測試。
從前面“手機淘寶組件化”的圖可以看出,組件化的核心層其實是容器層。
容器層主要分為兩大塊 1. 應用生命周期 2. 總線
而總線,就是核心組件之間的解耦的關鍵。 總線主要分為三塊: 1. URL 2. 服務 3. 消息
URL應該是整個總線傳輸的核心。 模塊通過URL跳轉的的方式,來進行模塊之間的消息傳遞。URL的用處是最多的,比如獲取相應對象,跳轉相應頁面,或者發起請求,都可以使用URL來進行。 這里拿蘑菇街URL跳轉的demo:MGJRouter,來進行舉例子。
MGJRouter主要就是通過各個模塊注冊相應的URL跳轉block,建立起一層URL與block的映射關系,然后調用方通過URL去訪問block,獲得結果。 通過URL的方式,調用方不需要去依賴其他模塊代碼,只需要直接調用,或者獲取相應的結果進行處理。
比如常見的頁面跳轉問題,通過URL路由,就可以直接跳轉到相應的頁面。 首先是注冊相應的URL內容,這里是詳情頁的內容。
[MGJRouter registerURLPattern:@"mgj://detail?id=:id" toHandler:^(NSDictionary *routerParameters) { NSNumber *id = routerParameters[@"id"]; // create view controller with id // push view controller}];然后調用方只需要調用
[MGJRouter openURL:@"mgj://detail?id=404"];就可以打開相應的界面。 不僅可以通過openURL的方式去打開一個URL,也可以通過objectForUrl去通過URL獲取一個對象,然后進行操作。
服務用來彌補URL無法處理或者難以處理的功能。 服務的作用主要體現在一些組件之間的功能調用,會比URL更佳通用。比如登陸,購物車等模塊的常用功能。 服務主要通過ModuleManager,去注冊PRotocol->Class的關系,獲得相應的對象,進行Protocol的方法調用。
比如登陸組件可以提供這樣的一個Protocol
@protocol User <NSObject>+ (NSString *)getUserName;@end可以看到通過協議可以直接指定返回的數據類型。然后在登陸組件內再新建個類實現這個協議,假設這個類名為UserImp,接著就可以把它與協議關聯起來
[ModuleManager registerClass:UserImp forProtocol:@protocol(User)];對于使用方來說,要拿到這個 UserImp,需要調用
Class cls = [ModuleManager classForProtocol:@protocol(User)];拿到之后再調用
id<User> userComponent = [[cls alloc] init];NSString *userName = [userComponent getUserName];就可以獲得用戶的用戶名了。
消息就是常見的NSNotification相關的消息轉發機制,在這里做一個消息的統一管理和分發給各個模塊,各個模塊自己去處理響應的消息。
總線的主要目的就是組件與組件之間的消息傳輸的解耦。 URL是總線中最主要的使用場景,包括頁面調用與發起請求等功能。 服務是組件間的調用方式。需要服務提供方提供與維護穩定的服務接口。 消息是在總線中進行統一管理與分發。
對于URL為核心的總線機制有以下好處: 1. 平臺統一 iOS,Android通過同一個URL總線在后臺進行管理與配置。 2. 自動降級 老版本解析不了URL,走老的邏輯依舊可用。新版本可以解析URL,走新的邏輯。 3. 中心分發 業務方分別注冊自己的URL攔截規則,配置在自己的模塊中。通過總線來中心分發響應能夠響應的模塊進行處理。
本文主要還是根據手機淘寶客戶端架構探索實踐和視頻,借鑒了蘑菇街 App 的組件化之路一些具體的實現思路,自己整理一下思路的總結和學習。
本文簡書地址
1.手機淘寶客戶端架構探索實踐 2.組件化架構漫談 3.蘑菇街 App 的組件化之路 4.iOS應用架構談 組件化方案
新聞熱點
疑難解答