什么是組件化
一般指項目根據(jù)不同的業(yè)務劃分的模塊化,也可以理解為通用控件的封裝巧号,提供接口方便別人調用浓瞪。
為什么要做組件化
組件化可以實現(xiàn)組件之間的隔離,每個組件單獨存在女轿,在做項目時可以利用現(xiàn)有功能組件進行拼裝箭启,達到快速開發(fā)的目的。
普通組件化
1蛉迹、創(chuàng)建一個主項目工程
2傅寡、創(chuàng)建兩個本地組件module
生成對應的podspec,后面可以單獨放到自己的倉庫,依賴pod管理北救。然后加上自己想要的功能代碼荐操,在主項目的podfile中添加pod引入
pod 'CTMediatorModule',:path=>'../CTMediatorModule'
pod 'BeeHiveModule',:path=>'../BeeHiveModule'
到這里生成的BeeHiveModule和CTMediatorModule兩個模塊其實已經制作完成可以正常的使用。
module結構如下:
主項目使用
#import "BeeHiveViewController.h"
- (void)clickBeeHiveButton {
BeeHiveViewController *beeViewController = [BeeHiveViewController new];
beeViewController.tipsStr = @"測試";
[self.navigationController pushViewController:beeViewController animated:YES];
}
可以看出現(xiàn)在的使用是需要引入BeeHiveModule模塊內的類珍策,如果存在組件之間的通信托启,各個組件之間都是直接依賴,就是組件直接#import被調用的組件攘宙,這些依賴關系凌亂而且復雜屯耸,在這種依賴關系下,如果想要多個組件并行開發(fā)蹭劈,必須跟其他組件開發(fā)者做好接口約定疗绣,這里可能會有一份組件的接口文檔,當組件接口出現(xiàn)變動時铺韧,需要通知所有此組件的使用者修改調用方法多矮,這種情況下,后期維護會非常困難祟蚀。
問題
如上所說工窍,這樣的組件之間存在大量的耦合割卖,維護成本增加,拓展性不強患雏。
解決
在這種情況下鹏溯,中間過度類應運而生,使得對組件的依賴轉移到中間類上淹仑。
BeeHive和CTMediator
BeeHive 和 CTMediator是兩個常用的中間件通用工具丙挽。
一、CTMediator
CTMediator內部是使用下列runtime方法實現(xiàn)的匀借。
使用CTMediator需要創(chuàng)建對應規(guī)則的target-action颜阐、CTMediato分類。
[圖片上傳失敗...(image-500833-1667375048529)]
1吓肋、創(chuàng)建target-action
target類的類名必須以Target_開頭凳怨,比如Target_A,action的方法名必須以Action_開頭是鬼,比如Action_CCModuleTestView:(NSDictionary *)params肤舞。
@implementation Target_ModuleTestView
- (UIView *)Action_CCModuleTestView:(NSDictionary *)params {
ModuleTestView *view = [[ModuleTestView alloc] init];
view.titleStr = [params objectForKey:@"titleStr"];//接收參數(shù)
return view;
}
@end
2、創(chuàng)建CTMediator的分類
此分類用于外部調用均蜜。
NSString *const kTarget_ModeuleTest = @"ModuleTestView";//Target_A中的A
NSString *const kAction_ModeuleTest = @"CCModuleTestView";//Action_XX中的XX李剖。
@implementation CTMediator (ModuleTest)
- (UIView *)moduleViewWithParams:(NSDictionary *)params {
UIView *view = [self performTarget:kTarget_ModeuleTest action:kAction_ModeuleTest params:params shouldCacheTarget:YES];
return view;
}
@end
外部調用:
- (void)clickCTMediatorButton {
UIView *view = [[CTMediator sharedInstance] moduleViewWithParams:@{@"titleStr":@"這是個參數(shù)--CTMediator"}];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view.mas_top).offset(400);
make.left.equalTo(self.view.mas_left).offset(100);
make.right.equalTo(self.view.mas_right).offset(-100);
make.height.mas_equalTo(200);
}];
}
中間件雖然可以使模塊間的具體實現(xiàn)與接口解耦,但無法避免對接口類的依賴關系囤耳。
二篙顺、BeeHive
BeeHive使用protocol-impClass方式來表示映射關系,protocol表示目標組件對外暴露的方法充择,impClass表示目標組件德玫。
1、BeeHive可以監(jiān)控系統(tǒng)事件聪铺,通常是Application生命周期事件化焕,例如DidBecomeActive、WillEnterBackground等铃剔。
一般做法是把BHAppDelegate接管原來的AppDelegate撒桨。
@interface AppDelegate : BHAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[super application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}
2、創(chuàng)建protocol(用來暴露外部供外部調用)和module類(用來注冊protocol-impClass映射關系)键兜。
[圖片上傳失敗...(image-abb4ce-1667375048529)]
BeeModule內部是注冊Protocol
@implementation BeeModule
//在啟動之后第一屏內容展現(xiàn)之前異步執(zhí)行模塊的初始化凤类,可以優(yōu)化啟動時時間消耗
BH_EXPORT_MODULE(YES)
- (void)modInit:(BHContext *)context {
//注冊模塊的接口服務
[[BeeHive shareInstance] registerService:@protocol(BeeServiceProtocol) service:[BeeHiveViewController class]];
}
@end
在調用組件時,調用者將目標組件的協(xié)議protocol作為參數(shù)傳給BeeHive普气,根據(jù)上述注冊的映射關系protocol-impClass谜疤,獲取協(xié)議protocol對應的實現(xiàn)類impClass。
- (void)clickBeeHiveButton {
id<BeeServiceProtocol> beeViewController = [[BeeHive shareInstance] createService:@protocol(BeeServiceProtocol)];
if ([beeViewController isKindOfClass:[UIViewController class]]) {
[beeViewController beeViewControllerParams:@"這個是個參數(shù)--beehive"];
UIViewController *beeVC = (UIViewController *)beeViewController;
[self.navigationController pushViewController:beeVC animated:YES];
}
}
現(xiàn)在只是依賴了BeeServiceProtocol。