2021-02更新
推荐阅读这篇文章 juejin.cn/post/684490…
2020年有幸能主导组件化开发,特此记录实践过程中遇到的问题。希望这篇可以抛砖引玉,吸引各位大神为社区贡献。如有不同见解,欢迎solo。
综述
- 组件化,重在复用与解耦,上层组件可依赖于下层组件,但不可以平行依赖,可以整复用,组件化的颗粒度很大程度决定了复用程度。
- 模块化,每个模块 = 多个组件+业务代码,每个模块是相互独立的,通过CTMediactor来进行交互。模块实际上就已经是业务代码,很难整体复用。
实践语言:Swift+Objectie-C混编
关于oc混编的问题,我在之前的文章中有介绍。
大部分模块使用的是Swift,部分使用Objective-C
组件的管理方式,私有pods + 索引库
模块的管理方式,私有pods,本地路径依赖
问题一:为什么模块不放到私有pods的索引库中,而是本地依赖?
最开始时,我们的组件和模块确实是放在一起的,每次都会发布,可是相对于单个组件来说,单个模块的发版次数,特别频繁,发布过程即使使用了自动发布脚本,整个过程,后期也到了5分钟甚至更多,也就意味着,我提交一次代码,需要5分钟甚至更多才行,这极大的影响了开发速度。而本地pod路径依赖就完全没有了这个问题。
问题二:如何创建私有pods + 索引库?
组件化的实践
组件化的架构图如下:
我将组件化分为4层
- 通用层
- 业务基础组件层
- 业务层
- 模块接口层
第一层:通用组件
通用组件又分为:核心层和扩展层
特点:与App无关,通用大部分app
核心层是扩展层的基础,扩展层是核心层的具体体现
核心层
大致包含以下内容:
- Core:swift、oc的扩展、特性
- Data:数据库封装
- RX:关于rxswift的相关封装
Core、Data、RX 提供了底层基础,相互独立,不可依赖
扩展层
大致包含以下内容:
- Net:网络,包含:重试、缓存、优先级、下载、上传等
- UI:包含UI的快捷初始化、常用的控件(LRButton、UDButton、YYText、YYLabel、SMS、Email、Snapkit、Modal)
- Permission: 权限
- Pay:支付
- Encrypt:加密
- Websocket:长连接
- Audio/Video:音视频
- Log:数据采集
扩展层严重依赖核心层以及第三方库,但注意,暴露给外界的接口中不包含第三库中的任何类,目的是减小第三方库的侵入性。我们需要都第三方库进行包装。
第二层:业务基础组件
这一层的组件,和业务弱相关,属于,换一个app改一改就可以重用的地步。其内容如下:
- Base/Protocol 父类:UIViewController、tabbar、navigation
- Net:网络先关配置,依赖上一层中的Net
- Permission:权限,依赖上一层中的Permission
- Theme:主题
- Resource:资源,图片、视频、文件等等
- Pay
- Log
- UserCenter
基础组件是业务组件的基础。颗粒度往往比较难把握 基础组件之间隔离,不相互交互
第三层:业务层
- 注册登录
- 语音房
- 商品屋
- 我的
- 消息
- 首页 具体业务实现,代码抽象度较低,基本上可复用的不多。业务组件之间隔离,不相互交互。
第四层:模块接口层(module header)
由于业务层中的组件之间相互隔离,不直接交互,各个模块之间无依赖,完全解耦。
那如何实现以下场景呢?
如:注册登录结束后(登录模块),跳转到首页(home模块)???
选择方案有路由和CTMediactor,这里我们选择的是CTMediactor,具体CTMediactor使用参考原作者的文章。
应不应该使用组件化进行开发?
目前项目中的组件个数已经超过了20个,虽然看着很多,但通用组件占比80%甚至更多,这些组件一旦被封装好,以后维护成本会大大较低。但前期的基础组件的开发会降低项目开发速度,所以需要斟酌时间是否允许。组件化又有什么好处呢?低耦合高重用,一旦一套组件化App开发完毕,再开一个新的app,将如鱼得水。
问题
这原本是我的第十八篇私人日记,因关于组件化有些困惑,特此整理。
1、不得不承认,当前组件化有些过度设计,组件的颗粒度较小,比如Permission基础组件,是否需要呢?
2、苹果审核会有代码重合度的要求,基础组件是否能重用?.a或者.framework是否不在统计范畴之内?知名的第三方库又是否在代码重合度的白名单中?这些都是未知数,给组件化带来了不确定性
3、连续push到不同模块的控制器后,如何pop到指定模块的控制器?
4、组件化的实践方案都是什么样子的?希望大家不吝赐教。
最后
知人者智,自知者明。 如有疑惑,不耻下问。