🐻 第十八篇 组件化与模块化的实践与一些想法

2,140 阅读5分钟

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、组件化的实践方案都是什么样子的?希望大家不吝赐教。

最后

知人者智,自知者明。 如有疑惑,不耻下问。

2020.1.15 整理于 北京·安贞
公众号:独立开发者基地