您的位置:首页 > 移动开发 > IOS开发

途牛在线预订业务关于组件化的思考和应用

2017-12-26 00:00 357 查看
关于组件化概念请移步http://https://my.oschina.net/u/1993252/blog/1595028

关于app整体组件化拆分已经有很多解决方案了,这里不作讨论。

问题背景

在线预订负责所有旅游产品的预订流程,由5个预订流程页面承载,不同预订流程按需会加载不同的资源(比如保险,交通是不同的2种资源)





那么就出现有的资源是某个旅游品类独有的,也有些资源是多个品类通用的。

我们考虑的是这些通用的资源,代码能不能做到复用(包括展示,交互,接口入参)?

这一步能做到,接下来既然资源能复用

能不能更进一步让服务端来告诉客户端需要加载哪些资源,实现接口控制的动态加载?

组件拆分

资源做成组件,这种复用的资源组件.
组件包含:生成view,内部交互逻辑,异步加载等

//组件协议
@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

页面自动加载

能不能更进一步让服务端来告诉客户端需要加载哪些资源,实现接口控制的动态加载?
资源组件化后,只需约定好类型,就可以通过接口报文实现动态加载。

接口数据约定

@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

为了动态加载组件,引入组件容器,帮助组件初始化。

@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,记得提醒我
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  iOS