其實之前寫過這麼一片相似的文章連接,利用字符串
+runtime
能作到命名域級別的解耦,其實這種作法很極端,編碼也很硬核,並且數據的類型也比較難肯定,其實這也是Objc自己動態弱類型語言的缺點.git
作了蠻久的iOS了,我就在前面的文章基礎上分析幾點本身的心得吧,若有不合適的地方,能夠指正哈.demo地址github
1.正常的業務模塊,沒什麼好說的,能夠寫UI,業務邏輯,工具這樣子的架構
2.AppDelegate在本模塊中的一個接收類,負責去解耦主工程中雜糅的業務,例如分享組件能夠把分享key註冊等事件放到這個類中app
3.ActionService分類,至關於組件對外暴露的一個接口,咱們利用宏去規範它的命名,到時利用router去調用便可,這個架構的複雜點主要就在於如何去維護這麼一個字符串常量列表,這裏能夠經過一些腳本掃描分類來減輕這個工做量.工具
UCACTION_SERVICE_EXTERN_METHOD(ModuleA, getVC, argu) {
return [ModuleAVC new];
}
複製代碼
UCACTION_SERVICE_EXTERN_METHOD
這個宏主要是拼接組件名和方法名成爲一個對象方法,起到規範命名的做用.組件化
1.router
,這裏來負責派發方法能夠這麼調用UCROUTER_OPEN_NATIVE(ModuleA, getVC, nil)
,只要輸入組件名,接口名便可,若是沒參數的話不傳就行.測試
2.AppDelegateExchange
這裏負責交換我寫的一個小工具UCAppDelegateReduce
和appDelegate
中的方法,而後聽從自身的生命週期到各個組件的AppDelegate
實現中去,支持位移枚舉配置,支持Swift
.編碼
+ (void)load {
UCAppDelegateMethodExchangeManager *manager = [UCAppDelegateMethodExchangeManager share];
// sendMessageType 是位移枚舉,能夠選擇本身想給子模塊派發的方法
UCAppDelegateConfigModel *model1 = [[UCAppDelegateConfigModel alloc] initWithModuleName:@"ModuleAAppDelegate" sendMessageType:didFinishLaunchingWithOptions];
UCAppDelegateConfigModel *model2 = [[UCAppDelegateConfigModel alloc] initWithModuleName:@"ModuleBAppDelegate" sendMessageType:handleOpenURL | didFinishLaunchingWithOptions];
[manager startExchangeMethodWithOriginalAppDelegateName:@"AppDelegate" newModuleAppDelegateConfigArray:@[model1, model2]];
}
複製代碼
3.ActionService
實際上是一個空類,每一個組件會實現他的一個分類用做一個對外接口的做用.spa
近期在拆主工程中的登陸模塊,我是想作成那種正確依賴,不依賴runtime這樣的解耦方式,只要導入組件,他會把全部依賴的組件進行導入,實現一個完整的功能這麼一個作法,比較理想,今天才把他作出來.設計
其實新項目,新模塊你作組件還好,儘可能少依賴外部,業務拆的清楚點基本還不算難作.拆老業務仍是很頭大的,有不少不屬於登陸模塊的卻還集成在登陸這個文件裏,我也是醉了,算是個吐槽吧.你導入一個,他要是依賴不少的話你還得想辦法去解決,這就是個惡性循環了,在這點上看這個命名域解耦雖然偷懶了,可是拆老項目組件仍是蠻好用的,我爲了正確設計依賴把別的組件也改了很多,把不屬於這個業務模塊的全清掉了.如今也能作到導入登陸的話可以導入相關依賴的模塊了,是個完整功能能夠運行了.
我的仍是偏向於正確的設計依賴,不要偷懶,因此咱們在寫項目的時候就要考慮好他的業務職責,儘可能保持模塊職責單一,依賴儘可能保持縱向,若是橫向依賴的話儘可能仍是用router
或者協議
去解決它.
另外不要爲了組件化而去作組件化,能夠把一些業務上或許可以複用的能夠拆一下.
拆的話能夠先從Service
層開始拆,好比分享,支付,map這些與業務牽扯比較小的,打下基石之後,拆業務也好拆一點.
最後這個AppDelegate
解耦的思路蠻不錯的,他的動態派發通過了400多條的UT測試,仍是比較穩的,也比較好擴展,這點能夠用用看.