前言
其實(shí)以前寫過這么一片類似的文章鏈接,利用字符串+runtime能做到命名域級(jí)別的解耦,其實(shí)這種做法很極端,編碼也很硬核,而且數(shù)據(jù)的類型也比較難確定,其實(shí)這也是Objc本身動(dòng)態(tài)弱類型語言的缺點(diǎn).
做了蠻久的iOS了,我就在前面的文章基礎(chǔ)上分析幾點(diǎn)自己的心得吧,如有不合適的地方,可以指正哈.demo地址
自己以前設(shè)計(jì)過得一個(gè)架構(gòu)
組件內(nèi)
1.正常的業(yè)務(wù)模塊,沒什么好說的,可以寫UI,業(yè)務(wù)邏輯,工具這樣子的
2.AppDelegate在本模塊中的一個(gè)接收類,負(fù)責(zé)去解耦主工程中雜糅的業(yè)務(wù),例如分享組件可以把分享key注冊(cè)等事件放到這個(gè)類中
-
3.ActionService分類,相當(dāng)于組件對(duì)外暴露的一個(gè)接口,我們利用宏去規(guī)范它的命名,到時(shí)利用router去調(diào)用即可,這個(gè)架構(gòu)的復(fù)雜點(diǎn)主要就在于如何去維護(hù)這么一個(gè)字符串常量列表,這里可以通過一些腳本掃描分類來減輕這個(gè)工作量.
UCACTION_SERVICE_EXTERN_METHOD(ModuleA, getVC, argu) { return [ModuleAVC new]; }
UCACTION_SERVICE_EXTERN_METHOD這個(gè)宏主要是拼接組件名和方法名成為一個(gè)對(duì)象方法,起到規(guī)范命名的作用.
組件外
1.
router,這里來負(fù)責(zé)派發(fā)方法可以這么調(diào)用UCROUTER_OPEN_NATIVE(ModuleA, getVC, nil),只要輸入組件名,接口名即可,如果沒參數(shù)的話不傳就行.-
2.
AppDelegateExchange這里負(fù)責(zé)交換我寫的一個(gè)小工具UCAppDelegateReduce和appDelegate中的方法,然后遵從自身的生命周期到各個(gè)組件的AppDelegate實(shí)現(xiàn)中去,支持位移枚舉配置,支持Swift.+ (void)load { UCAppDelegateMethodExchangeManager *manager = [UCAppDelegateMethodExchangeManager share]; // sendMessageType 是位移枚舉,可以選擇自己想給子模塊派發(fā)的方法 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其實(shí)是一個(gè)空類,每個(gè)組件會(huì)實(shí)現(xiàn)他的一個(gè)分類用作一個(gè)對(duì)外接口的作用.
近期在項(xiàng)目拆組件的一點(diǎn)心得
近期在拆主工程中的登錄模塊,我是想做成那種正確依賴,不依賴runtime這樣的解耦方式,只要導(dǎo)入組件,他會(huì)把所有依賴的組件進(jìn)行導(dǎo)入,實(shí)現(xiàn)一個(gè)完整的功能這么一個(gè)做法,比較理想,今天才把他做出來.
其實(shí)新項(xiàng)目,新模塊你做組件還好,盡量少依賴外部,業(yè)務(wù)拆的清楚點(diǎn)基本還不算難做.拆老業(yè)務(wù)還是很頭大的,有很多不屬于登錄模塊的卻還集成在登錄這個(gè)文件里,我也是醉了,算是個(gè)吐槽吧.你導(dǎo)入一個(gè),他要是依賴很多的話你還得想辦法去解決,這就是個(gè)惡性循環(huán)了,在這點(diǎn)上看這個(gè)命名域解耦雖然偷懶了,但是拆老項(xiàng)目組件還是蠻好用的,我為了正確設(shè)計(jì)依賴把別的組件也改了不少,把不屬于這個(gè)業(yè)務(wù)模塊的全清掉了.現(xiàn)在也能做到導(dǎo)入登錄的話能夠?qū)胂嚓P(guān)依賴的模塊了,是個(gè)完整功能可以運(yùn)行了.
總結(jié)
個(gè)人還是偏向于正確的設(shè)計(jì)依賴,不要偷懶,所以我們?cè)趯戫?xiàng)目的時(shí)候就要考慮好他的業(yè)務(wù)職責(zé),盡量保持模塊職責(zé)單一,依賴盡量保持縱向,如果橫向依賴的話盡量還是用router或者協(xié)議去解決它.
另外不要為了組件化而去做組件化,可以把一些業(yè)務(wù)上或許能夠復(fù)用的可以拆一下.
拆的話可以先從Service層開始拆,比如分享,支付,map這些與業(yè)務(wù)牽扯比較小的,打下基石以后,拆業(yè)務(wù)也好拆一點(diǎn).
最后這個(gè)AppDelegate解耦的思路蠻不錯(cuò)的,他的動(dòng)態(tài)派發(fā)經(jīng)過了400多條的UT測(cè)試,還是比較穩(wěn)的,也比較好擴(kuò)展,這點(diǎn)可以用用看.