casatwy組件化方案


整體架構

casatwy組件化方案分爲兩種調用方式,遠程調用和本地調用,對於兩個不同的調用方式分別對應兩個接口。

  • 遠程調用通過AppDelegate代理方法傳遞到當前應用後,調用遠程接口並在內部做一些處理,處理完成後會在遠程接口內部調用本地接口,以實現本地調用爲遠程調用服務

  • 本地調用由performTarget:action:params:方法負責,但調用方一般不直接調用performTarget:方法CTMediator會對外提供明確參數和方法名的方法,在方法內部調用performTarget:方法和參數的轉換。

16270478-00fb1f35705bb080

casatwy提出的組件化架構

架構設計思路

casatwy是通過CTMediator類實現組件化的,在此類中對外提供明確參數類型的接口,接口內部通過performTarget方法調用服務方組件的TargetAction。由於CTMediator類的調用是通過runtime主動發現服務的,所以服務方對此類是完全解耦的。

但如果CTMediator類對外提供的方法都放在此類中,將會對CTMediator造成極大的負擔和代碼量。解決方法就是對每個服務方組件創建一個CTMediatorCategory,並將對服務方的performTarget調用放在對應的Category中,這些Category都屬於CTMediator中間件,從而實現了感官上的接口分離。

17270478-488134663e7c7744

casatwy組件化實現細節

對於服務方的組件來說,每個組件都提供一個或多個Target類,在Target類中聲明Action方法。Target類是當前組件對外提供的一個“服務類”Target將當前組件中所有的服務都定義在裏面,CTMediator通過runtime主動發現服務

Target中的所有Action方法,都只有一個字典參數,所以可以傳遞的參數很靈活,這也是casatwy提出的Model化的概念。在Action的方法實現中,對傳進來的字典參數進行解析,再調用組件內部的類和方法。

架構分析

casatwy爲我們提供了一個Demo,通過這個Demo可以很好的理解casatwy的設計思路,下面按照我的理解講解一下這個Demo

18270478-106c9ecc613498bd

文件目錄

打開Demo後可以看到文件目錄非常清楚,在上圖中用藍框框出來的就是中間件部分,紅框框出來的就是業務組件部分。我對每個文件夾做了一個簡單的註釋,包含了其在架構中的職責。

CTMediator中定義遠程調用和本地調用的兩個方法,其他業務相關的調用由Category完成。

 

 

1

2

3

4

// 遠程App調用入口

- (id)performActionWithUrl:(NSURL *)url completion:(void(^)(NSDictionary *info))completion;

// 本地組件調用入口

- (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params;

CTMediator中定義的ModuleACategory,對外提供了一個獲取控制器並跳轉的功能,下面是代碼實現。由於casatwy的方案中使用performTarget的方式進行調用,所以涉及到很多硬編碼字符串的問題casatwy採取定義常量字符串來解決這個問題,這樣管理也更方便。

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#import "CTMediator+CTMediatorModuleAActions.h"

 

NSString * const kCTMediatorTargetA = @"A";

NSString * const kCTMediatorActionNativFetchDetailViewController = @"nativeFetchDetailViewController";

 

@implementation CTMediator (CTMediatorModuleAActions)

 

- (UIViewController *)CTMediator_viewControllerForDetail {

    UIViewController *viewController = [self performTarget:kCTMediatorTargetA

                                                    action:kCTMediatorActionNativFetchDetailViewController

                                                    params:@{@"key":@"value"}];

    if ([viewController isKindOfClass:[UIViewController class]]) {

        // view controller 交付出去之後,可以由外界選擇是push還是present

        return viewController;

    } else {

        // 這裏處理異常場景,具體如何處理取決於產品

        return [[UIViewController alloc] init];

    }

}

下面是ModuleA組件中提供的服務,被定義在Target_A類中,這些服務可以被CTMediator通過runtime的方式調用,這個過程就叫做發現服務

我們發現,在這個方法中其實做了參數處理和內部調用的功能,這樣就可以保證組件內部的業務不受外部影響,對內部業務沒有侵入性

 

 

1

2

3

4

5

6

- (UIViewController *)Action_nativeFetchDetailViewController:(NSDictionary *)params {

    // 對傳過來的字典參數進行解析,並調用ModuleA內部的代碼

    DemoModuleADetailViewController *viewController = [[DemoModuleADetailViewController alloc] init];

    viewController.valueLabel.text = params[@"key"];

    return viewController;

}

 

命名規範

在大型項目中代碼量比較大,需要避免命名衝突的問題。對於這個問題casatwy採取的是加前綴的方式,從casatwyDemo中也可以看出,其組件ModuleATarget命名爲Target_A,被調用的Action命名爲Action_nativeFetchDetailViewController:

casatwy將類和方法的命名,都統一按照其功能做區分當做前綴,這樣很好的將組件相關和組件內部代碼進行了劃分。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章