前言

10 月份技术数睿大讲堂轮到我了,那这期我准备了分享 - 组件化之路。好好总结下组件化的相关知识点,也好复习这块

目录

  • 什么是组件化
    • 组件化的概念
    • 组件化的好处
  • 组件化的分层
    • 组件化的 4 基本个原则
    • 组件间依赖关系的 3 个基本原则
    • 组件库的分层
    • 组件化的过程
  • 组件化的过程
    • 基于 Cocoapod 管理私有组件
    • 简化 * 自动化更新私有组件
    • 组件化通讯 - 路由
  • 总结

什么是组件化?

痛点

当着我们的业务越来越多,项目越来越大。我们无可避免遇到项目痛点,就会逐渐暴露出来:

  • 代码混乱
  • 职责不清楚,你中有我,我中有你
  • 编译越来越慢,特别大型项目中,完整项目编译时间动不动 20 分钟以上,甚至个把小时,你们都知道客户端开发不像前端那样,有热加载加持,所以稍有改动就要重新编译,这是我们难以忍受地方
  • 难以支撑的业务测试

又例如我们中台 IM 项目如果不做成组件,那每次引入只能复制粘贴 ,后期维护修改就非常麻烦

解决方案:组件化

组件化的概念

组件化概念:将一个单一工程的项目, 分解成为各个独立的组件, 然后按照某种方式, 任意组织成一个拥有完整业务逻辑的工程。

组件化的好处

  • 独立:
    • 独立编译提高编译速度
      • 举例:钢铁侠直接穿戴手部机甲,肯定比穿戴全套的快
    • 自由选择开发模式
      • 举例:钢铁侠开发完手部机甲用的MVC,感觉这种不好,开发腿部的时候用MVVM了
    • 方便 QA 针对性测试
      • 举例:钢铁侠开发完手部机甲,直接穿戴测试手部机甲即可
    • 业务隔离
      • 举例:钢铁侠想升级手部机机甲的激光模块,动手就可以,别的地方不用管
  • 组合/复用:
    • 便于各业务功能拆分、抽离、复用
      • 举例:钢铁侠想给美队使用机甲腿,直接把腿部机甲拿过来用即可
  • 易维护:
    • 业务分层、解耦、可维护性更高
      • 举例:钢铁侠可以雇佣多个团队同步开发,你开发手臂,我开发腿部,互不干扰,完工拼装即可

组件化实施难点

  • 技术代码和业务夹杂难拆分
  • 相互独立模块,如何调用
  • 组件怎么划分
  • 如何调试,如何集成

不急,我们通过组件化的分层及过程来解决上述问题点。

组件化的分层

讲分层前,我们需要知道组件化的 4 个基本原则 && 组件化间关系的 3 个基本原则

组件化的 4 个基本原则

  • 单一性原则,指每个组件仅提供一个功能。分而治之是组件化的中心思想,每个组件都有自己固定的职责和清晰的边界,专注的做一件事,这样这个组件才能良性的发展。
  • 抽象性原则,指组件提供的功能抽象应该尽量稳定,具有高复用度。而稳定的直观表现就是对外暴露的接口很少发生变化,要做到这一点,需要我们提升对功能的抽象总结能力,在组件封装时做好功能抽象和接口涉及,将所有可能发生变化的因子都在组件内部做好适配,不要暴露给它的调用方。
  • 稳定性原则,指不要让稳定的组件依赖不稳定的组件。
  • 自完备性原则,指组件要尽可能做到自给自足,尽量减少对其他底层组件的依赖,达到代码的可复用目的。

组件间依赖关系的 3 个基本原则

  • 同层级组件间不应该产生依赖
  • 上层组件可以依赖下层组件
  • 下层组件不能依赖上层组件

组件化的分层

  • 业务组件(上层组件)
    • 独立业务,比如我们 房屋交易 划分首页,搜寻,新闻,我的,当然首页的业务可以继续细化为新建案,租售等业务
    • 基础业务,比如账号登录,内购支付,api签名
  • 功能组件(中层组件)
    • 基本UI 组件,比如轮播器,菜单,
    • 功能性组件,比如断点续传,录音播音组件等封装
  • 基础组件(下层组件)
    • 基本配置比如常量,宏定义,分类,扩展,工具类,网络请求等组件封装

一个完整的 App,组件化的分层如图

组件化的过程

基于 Cocoapods 管理私有组件

基于Cocoapod 管理工具去管理封装成一个个私有组件,步骤如下

  • 创建远程索引库和私有组件库仓库
  • 将远程索引库添加到本地 pod repo add 索引库名称 索引库地址
  • 创建一个 pod 模板组件库 pod lib create 组件名称
  • 上传代码和打标签
  • 提交 spec 至私有索引库
  • 使用 source 索引库url pod '组件名称'

Pod 私有库的过程,以 SRIMProject 为例

  • 第一步:创建远程IM索引库和IM私有库


  • 第二步:添加私有索引库到本地 pod repo add SRIMProjectSpec https://code.addcn.com/app/iOS/SRIMProjectSpec

  • 第三步:创建一个pod模板库
    • pod lib create SRIMProject
    • 添加组件内容:删除 ReplaceMe.m 文件,添加基础组件相关的内容到 Classes 文件夹中
    • 安装与测试本地库,执行安装命令 pod install
    • 重点修改 Spec 文件

  • 第四步:上传代码和打标签

    • git remote add origin 远程私有库地址
    • git push origin master
    • git tag ‘1.3.1’
    • git push –tags
  • 第五步:提交 spec 至私有索引库

    • 现在执行本地校验命令 :pod lib lint --private --sources=master,SRIMProjectSpec --allow-warnings
    • 如果输出:SRIMProject passed validation.即表示校验成功
    • 提交 podspec:pod repo push SRIMProjectSpec SRIMProject.podspec --verbose --allow-warnings
    • 提交成功搜索下私有库 pod search SRIMProject

  • 第六步:使用私有库
    • 添加私有库搜引地址 source 'https://code.addcn.com/app/iOS/SRIMProjectSpec'
    • 添加使用的组件库名 pod 'SRIMProject','1.2.0'

是不是觉得私有库迭代更新比较繁琐??

简化*自动化更新私有组件

  1. 更新组件过程太繁琐,重复。怎么办?
    • 答案:通过 fastlane + jenkins 实现自动化构建组件
  2. 步骤划分
    • 安装 fastlane 环境 sudo gem install -n /usr/local/bin fastlane
    • 搭建 Jenkins 环境 brew install jenkins (ruby 环境及brew 已安装过)
    • 脚本配置
      • 项目目录下创建并修改Fastfile文件
      • 配置 shell 构建脚本 build_iOS.sh
      • 配置 Jenkins 平台

Jenkins 构建平台

组件化通讯 - 路由

成龙大哥的烦恼,从这张图我们发现什么问题呢? 组件间通讯产生互相依赖问题
解决方案:路由解耦

  • 什么是路由:路由广义的讲就是通过某个协议或规定把信息从源地址传输到目的地址的过程
  • 路由管理作用:统一管理组件间的页面跳转,解决组件间相互依赖问题

路由的解决方案

  • 目前有三种解决方案:分别是 URL Router ,Target-action, Protocol-Class
    • URL Router:通过在启动时注册组件提供的服务,把调用组件使用的 url 和组件提供的服务 block 对应起来,保存到内存中。在使用组件的服务时,通过url找到对应的block,然后获取组件服务
    • Target-action:遵循一定函数命名规范,通过 runtime 的 NSSelectorFromString 的来获取对应组件服务
    • Protocol-Class:通过 protocol 定义服务接口,组件通过实现该接口来提供接口定义的服务,具体实现就是把 protocol 和 class 做一个映射,同时在内存中保存一张映射表,使用的时候,就通过 protocol 找到对应的class 来获取需要的组件服务

路由的解决方案对比如图

总结

组件化是一把双刃剑

  • 组件化的优点:

    • 独立:独立编写、编译、运行、测试
    • 重用:功能代码的重复使用,比如不同项目使用同一功能模块
    • 高效:任意增删模块,实现高效迭代
    • 速度:组件化还可以配合二进制化, 进一步提高项目编译速度
  • 组件化的不足:

    • 会增加开发者的学习成本
    • 组件拆分颗粒度把握不好,会产生很多冗余代码
    • 图片资源管理不好,会产生很多冗余图片
    • 组件化过程中,会带来一些组件之间的调试问题,前期会影响团队效率

提问:你认为组件化的核心作用是?

我的理解是: 业务解耦,提高编译速度,从而提高研发效率

Jenkins管理的组件库

我们 tw591 app

tw591 组件库化图