1 组件化概念介绍
1.1 概念
将一个单一工程的项目, 分解成为各个独立的组件; 然后按照某种方式, 任意组织成一个拥有完整业务逻辑的工程
1.2 产生原因
如果是单一工程, 业务线比较少, 人数比较少, 一般的开发模式没有任何问题,但是一旦项目发展慢慢庞大, 业务主线增多,开发人员增多, 就会暴露出一系列问题,耦合比较严重,编译速度慢,测试不独立,无法使用自己擅长的设计模式
1.3 组件化最终可达到效果
- 组件的独立:独立编写,独立编译,独立运行,独立测试
- 资源的重用:功能代码的重复使用
- 高效的迭代:增删模块
- 可配合二进制化, 最大化的提高项目编译速度
1.4 组件化实践考虑的问题
需要把哪些内容划分成为一个组件?
- 基础组件:基本配置(常量/宏),分类(各种系统类的扩展),网络(对AFN的封装/对SDWebImage的封装),工具(日期时间处理/文件处理/设备信息/…)
- 功能组件:控件(轮播器/选项菜单/图文菜单/…),功能(断点下载/…)
- 业务组件:业务线1(子业务线1/子业务线2/…),…
每个组件以一个什么样的形式存在?
- 组件内部:根据设计模式进行划分文件夹结构
- 组件形式:每个组件都是以pod库的形式存在
- 组件测试:单独的测试工程
以怎样的形式集成各个组件?
- 通过cocoapods的形式安装各个组件
组件之间如何通讯?
- 披露公开API
- 通过中间件的中转
附加问题:
- 如何提高编译速度?
- 如何解决重复的流程操作?
- 库的升级维护问题?
1.5 组件化过程中, 分离每个组件的难点-解耦
如果一个组件里面依赖的其他公共功能, 该如何处理?
- 直接copy代码,对于一些不重要的工具方法,也可以直接copy到内部来用。
- 把组件依赖的代码先做成一个Pod库,然后依赖Pod库
如果组件内部, 需要对接某个服务, 该如何处理?
- 比如内部涉及到加载网络图片,使用一个block或delegate(协议)把这部分职责丢出去。
2. 组件化开发主要步骤
2.1 创建模版库
- pod lib create xxx
2.2 拖入代码或者直接在模版库开发
2.3 关联远程代码仓库
- git remote add origin https://git.xxxxx/xxxxx.git
2.4 修改模版库的spec文件
2.5 提交代码到远程代码仓库
- git add .
- git commit -m “log”
- git push origin master
2.6 打标签,并且提交标签到远程地址
- git tag
- git tag ‘0.1.0’
git push –tags
git tag -d 0.2 #先删除本地标签
- git push origin :0.2 #删除远程标签
2.7 验证spec,并且提交到本地私有索引库
- pod spec lint
- pod repo push FunkyFMSpecs FunkyFMMain.podspec
- pod repo push FunkyFMSpecs FunkyFMMain.podspec –allow-warnings 可以忽略警告
3. 组件间通讯
3.1 什么是组件间通讯?
- 比如现在有很多业务组件, 在另外一个组件内部需要调用另外一个组件中的服务, 或者打开另外一个组件中的控制器, 并传值, 如果直接在另外一个组件导入了另外一个组件的头文件, 则产生了物理上的依赖关系
3.2 宿主工程作为中间件
- 对每一个组件,统一披露API,在宿主工程中进行调用
3.3 MGJRouter方案
- 原理:
- 通过url向中间件MGJRouter注册服务, 其他地方通过url, 从中间件MGJRouter获取服务, 框架在维护一个url-block的表格
- 特点:
- 每个业务组件, 都需要依赖这个框架
- url维护成本高
- 可以在组件内部任何地方调用/注册服务, 没有必要统一组件接口服务
3.4 target-action方案
- 原理:
- 每个组件, 提供一个统一披露的接口文件
- 额外的维护一个中间件的分类扩展(在此处进行硬解码,通过运行时进行物理解耦)
- 其他地方通过target-action;的方案进行交互
- 特点
- 统一了组件api服务
- 组件与框架之间无依赖关系
- 需要额外维护中间件类扩展