iOS项目组件化
背景
我们提供车联网全套解决方案,向外输出能力是其中一种。
关于如何与第三方企业合作,向外输出技术能力,无非就三种方式
可以看出,SDK方案相对可取。 如果仅仅为第三方封装SDK显然是资源浪费。
什么是组件化
将程序中功能相对独立的部分打包在一起形成模块,并且减少模块之间的直接依赖。
- 底层是中间件(业务无关的组件,如网络请求、存储、工具类),共同为上层业务提供服务,允许相互引用(但应尽量减少);
- 业务组件在上层依赖中间件,相互之间不允许直接引用。
为什么要用组件化研发方案
因素 |
---|
对内敏捷开发,解决跨团队、异地办公的问题 |
对外输出能力 |
架构要具有延伸性,为可预见的业务发展提供技术支持 |
在业务初期,采用单一工程开发周期更短,是合适的开发模式,但是随着业务复杂度不断增加,工程越来越庞大,开发人员逐渐增多,单一工程的开发模式会出现一系列问题:
问题点 | 举例 |
---|---|
耦合严重 | 组件之间依赖过于复杂,维护成本高 |
容易出现冲突 | xib 或者代码冲突机会大大增加 |
开发效率低 | 每次都需要编译整个项目 |
近两年组件化开发较为火热,总的来说,组件化最大的好处就是低耦合,这是程序开发最基本的原则
收益 |
---|
维护成本低 |
复用性好 |
版本控制冲突少 |
加快编译速度 |
方便 QA 有针对性地测试 |
当然组件化也有一些代价:
代价 |
---|
对新加入团队的研发人员不友好 |
开发流程变复杂,开发成本变高 |
模块化初期投入较大,影响发版节奏 |
从技术角度来讲,组件化是有套路的,将业务根据颗粒度进行划分,基于git管理代码,抽取出不同的组件, 将不同的组件归集到不同的私有仓库,基于Cocospods
管理这些私有仓库,通过壳子工程,抹上胶水将这些组件串通起来,胶水就是所谓的路由或者中间人。
我们APP进行业务开发的同时,沉淀下来的各个独立模块即可向第三方输出能力。
实现方式
- 对于基础能力库,直接封装成 pod 放在私有的 repo 上即可
- 对于业务组件,重点是如何解决耦合问题
第二点问题的本质是组件之间服务的提供和调用。 需要解决两个问题:
- 服务的发现
- 服务的调用,并且避免中间人对组件的依赖。
方案分析已在【组件化方案分析】中有详述,本文不再讨论。
对胶水的选择
以上分析的三种方案,我们统称为胶水,它们各有优缺点,没有一个是360°完美
的。
综合考虑项目实际情况后,对于APP层面的胶水,选择以Protocol + Wrapper
为主, 少量openURL
配合的方式。
胶水构成 | 主要任务 |
---|---|
Dubbo | 治理组件间通讯,如何提供服务、如何发现服务、如何使用服务 |
URLRouter | 用来处理推送、H5跳转、支付回调、分享等 |
借鉴后台框架Dubbo及阿里的BeeHive设计思路,我们对胶水层进行优化。 我们将每个组件提供的能力理解为向外提供服务。 业务组件既是服务提供方又是服务使用者。
Dubbo提供的能力 |
---|
Module治理 |
Service治理 |
事件治理 |
Dubbo不是本篇讨论重点,举个简单实例,不再发散讨论。 发现服务及使用服务
id<XXLoginModuleService> service = [XXDubbo createService:@protocol(XXLoginModuleService)];
if(service) {
@XX_WEAKIFY(self)
[XXHUD showLoading];
[service logoutWithCompletion:^(NSError * _Nullable error) {
[XXHUD hideHUD];
}];
}
对外接口规范及实现方式
原则是
- 可读性、可维护性、可变更性
- 利益最大化,满足项目需要即可,尽量规避缺点
- 对外提供的能力,表达方式即规范要一致
- 组件内部,对外隐藏具体实现,可以使用
MVC、MVVM、MVP、APO
等等方式,自由发挥,需要研发团队协商并建立规范。
Protocol + Wrapper
- Protocol定义好对外提供的能力
- Wrapper ,一般是组件提供方的私有类,不对外暴露,用来实现Protocol能力
网易云IM的iOS SDK很好的运用了Protocol + Wrapper
方案,顺丰内部员工的IM协同办公APP使用了这个SDK,经得起考验。
https://netease.im/im-sdk-demo