途牛在線預訂業務關於組件化的思考和應用

關於組件化概念請移步http://https://my.oschina.net/u/1993252/blog/1595028數組

關於app總體組件化拆分已經有不少解決方案了,這裏不做討論。app

問題背景

在線預訂負責全部旅遊產品的預訂流程,由5個預訂流程頁面承載,不一樣預訂流程按需會加載不一樣的資源(好比保險,交通是不一樣的2種資源)異步

輸入圖片說明 輸入圖片說明

那麼就出現有的資源是某個旅遊品類獨有的,也有些資源是多個品類通用的。組件化

  • 咱們考慮的是這些通用的資源,代碼能不能作到複用(包括展現,交互,接口入參)?

這一步能作到,接下來既然資源能複用ui

  • 能不能更進一步讓服務端來告訴客戶端須要加載哪些資源,實現接口控制的動態加載?

組件拆分

資源作成組件,這種複用的資源組件. 組件包含:生成view,內部交互邏輯,異步加載等atom

//組件協議
@protocol ModuleContainerProtocol;
@protocol ModuleProtocol <NSObject>

@required
@property (nonatomic, weak) UITableView *tableView;
@property (nonatomic, weak) id<ModuleContainerProtocol> moduleManager;
@property (nonatomic, strong) ModuleData *baseInfo;
@property (nonatomic, strong, readonly) NSArray *datasource;
@property (nonatomic, assign) NSInteger loadPriority;//!< 加載優先級,值越小越先進行異步加載

- (void)modulesDidLoad;
- (void)allModulesDidLoad;
/**
 模塊依賴的數組

 模塊依賴的數組加載完成以後會調用該模塊的`-dependentModulesDidLoad`方法。
 
 @return 模塊所依賴模塊的 *類* 數組
 */
- (NSArray<Class> *)dependentModules;

/**
 模塊依賴的數組加載完成以後會調用該模塊的`-dependentModulesDidLoad`方法。
 */
- (void)dependentModulesDidLoad;

/**
 是否初始化數據完成,若是初始化完成,`-dependentModulesDidLoad`方法將不會被調用。
 若是不實現該方法,默認返回`True`。

 @return YES: 完成初始化,再也不調用`-dependentModulesDidLoad`方法。
 *       NO:一旦依賴的模塊完成,會再次調用`-dependentModulesDidLoad`方法。
 */
- (BOOL)shouldFinishInitData;

//接收消息
- (id)receiveMessage:(ModuleMessage *)message;

@end

頁面自動加載

能不能更進一步讓服務端來告訴客戶端須要加載哪些資源,實現接口控制的動態加載? 資源組件化後,只需約定好類型,就能夠經過接口報文實現動態加載。.net

接口數據約定code

@interface ModuleData : NSObject
@property (nonatomic, copy) NSString *listType;//!< 類型,字符串匹配到不一樣的組件,實現組件初始化
@property (nonatomic, assign) BOOL canShow;//!< 容許展現
@property (nonatomic, assign) BOOL asynFlag;//!< 容許異步加載
@property (nonatomic, strong) id data;//!< 初始化View數據
@end

爲了動態加載組件,引入組件容器,幫助組件初始化。component

@protocol ModuleContainerProtocol <NSObject>

/**
 構建模塊。
 
 根據`moduleInfoArray`數據來生成相應的模塊。

 @param moduleInfoArray Module的數據數據
 */
- (instancetype)initWithModuleDatas:(NSArray<ModuleData *> *)moduleDatas;
/**
 註冊消息
 
 @param message 消息
 @param component 訂閱消息的組件
 */
- (void)registerMessage:(NSString *)message module:(id)module;

/**
 註銷消息
 
 @param message 消息d
 @param component 訂閱消息的組件
 */
- (void)unregisterMessage:(NSString *)message module:(id)module;

/**
 發送消息,而且會帶回響應該消息組件的處理結果。
 
 @param message 消息
 @return 全部響應處理的結果
 */
- (NSArray *)sendMessage:(ModuleMessage *)message;

/**
 從新加載全部模塊
 */
- (void)reload;

/**
 從新加載指定模塊

 @param module 須要從新加載的模塊
 */
- (void)reloadDataInModule:(id)module;

#pragma mark - 滾動到對應module
- (void)scrollToModule:(id)module scrollPosition:(UITableViewScrollPosition)position;

@end

收益

輸入圖片說明

  • 代碼收益,二進制文件從16M減小到10M
  • 業務維護方便,產品迭代變快
  • 支持動態加載,對已經存在的組件,新業務品類接入,不用二次開發,配置一下便可。

稍後附上代碼demo,記得提醒我blog

相關文章
相關標籤/搜索