代码手艺人

组件化开发调研

Word count: 1,930 / Reading time: 7 min
2018/07/23 Share

前言

组件化开发是一种软件架构思想,其目的是提高软件可维护性、代码复用性,有以下几个特点:

  1. 组件独立于项目,与项目之间是热插拔的关系,类似linux系统中的服务,启动了就可使用,没启动就不能使用。例如A项目使用a、b、c三个组件,B项目使用b、c、d三个组件。

  2. 组件之间互相独立,即使a组件要依赖于b组件,a组件也不会直接引入b组件。而是通过协议调用、消息转发等方式解耦

  3. 组件内部保持职责单一,一个组件只做与它业务相关的事,与之无关事情代理给其他组件做。

组件化的目标:

  1. 多APP共用一套组件,每个组件单独维护,组件的更新维护不影响业务层开发。

  2. 不同APP以配置的方式接入自己所需要的组件。

  3. 新组件开发后能快速铺向所有业务。

  4. 未来的新APP,共用一套底层框架,能保证产品的稳定性和快速迭代。

Part1 目前代码结构中的问题

1)代码复用性低,每个业务都维护自己的代码

2)业务内各个模块耦合严重。模块内职责混乱,如FXCommonTool,目前FXCommonTool里面的功能有:网络请求、功能函数(获取当前时间、mac地址等)、网络状态、UI弹框、开启定位。。。

3)Appdelegate代码混乱。目前Appdelagate里的代码有:设置环境、bugly初始化、友盟初始化、融云初始化、百度地图初始化、蓝牙相关操作、日志组件功能、腾讯云初始化、广告组件。。。。

4)项目目录结构混乱

基础库、系统类扩展、UI组件、功能组件、三方库、上层业务代码、资源文件几乎都在同一级目录下

Part2 组件化方案

iOS组件化方案基于Pod代码管理技术 + 组件协议解耦技术 + App路由解耦技术 + AppDeletegate瘦身技术 四个部分组成。其中组件代码会用cocopods私有库管理,与主工程分开维护。

为何不使用第三方框架:

网上开源框架各有各的问题,要么无法满足需求,要么学习成本高,要么实现方式不够简洁

a)BeeHive 阿里解耦框架 https://github.com/alibaba/BeeHive
优点:

  1. 涵盖了几乎除runtime外所有组件化的技术
  2. 功能丰富,比如plist配置模块、异步加载等

缺点:

  1. 学习成本高,框架概念模糊,框架内一个模块包含多个服务,容易让人混淆
  2. 在系统事件上封装做了许多封装,其实比较多余,造成理解上的困难
  3. 一些我们用不到的功能,对我们来说是累赘

b)CTMediator(runtime解耦策略)

问题:

  1. 无法调用实例方法
  2. 无法支持调用多参函数,无法传入非id型变量
  3. 因为以上两个问题,用CTMediaor就没办法解第三方库耦合,最多用来解自己写的组件

一、Pod代码管理技术

组件代码用pod引入,使用pod既能管理三方库、也能管理子模块代码以及资源文件。

a)用pod引用工程代码

b)用pod引入资源

c)用pod管理子模块依赖

总结:采用Pod可方便的管理git子模块,只需学习配置规则无后续成本。Pod在配置好以后,在Pod install时会自动生成xcode子工程,Pod代码管理方案已被业界普遍采用。

二、组件协议解耦技术 (PHIServiceManager)

组件化的目的是模块解耦,解耦的目的是为了模块复用,所以各个模块间的耦合需要在组件化的过程中去掉。

a) 根据设计模式的“依赖倒置原则”,高层不依赖于低层的实现,依赖于抽象;具体实现依赖于抽象

b) 设计组件时,先根据组件的功能定义好组件对外的接口。并把接口封装成组件的协议

c)高层面向协议调用组件;组件内部依据协议实现组件。

总结:使用协议解耦是软件工程中常用到的手段,对于OC来讲,正好提供了协议功能。

三、App路由解耦技术 (PHIRoute)

路由解耦的核心思想是消息分发,“把事情交给对应的人去做”。实现思路是把事件通过路由管理器分发到对应的组件,对应的组件执行完成后,通过路由管理器再带回结果。事件分发以URI为载体,带入事件名+参数 。 例如:做页面的跳转,事件发送到模块后,通过参数初始化好controller,再调用共用的navigation push。

a)路由管理器的实现

b)路由注册(收到事件后的处理方法)

c)路由事件发起

Q: 为何不用runtime做路由

A: runtime做路由,swift的模块就无法解耦。swift模块可用消息分发路由解耦。

总结:基于路由技术做解耦比组件协议解耦更加灵活,组件协议虽然解除了耦合,但还是需要依赖抽象的协议。某些时候还是略显麻烦,基于路由事件分发,路由事件发起者不需要引用接受者的模块,直接发起事件,如果接受者在管理器中有注册,则事件得到处理。

四、AppDelegate瘦身技术 (PHIEngine)
Appdelegate承载系统许多模块初始化 & APP 状态切换后相应的工作,因此许多项目的Appdelegate非常庞大难以维护。AppDelegate瘦身技术的原理是把系统消息如didfinishLanuc通过“app管理器”分发出去,再由各个模块分别处理。

a)app管理器实现

b)模块注册

c)事件响应

总结:AppDelegate瘦身技术能有效解决Appdelegate代码杂乱的问题。

四、Runtime解耦技术(PHIMediator)

对于第三方库带来的耦合,由于不方便注入代码,使用路由解耦会比较麻烦。
这种场景适用于Runtime解耦技术,通过Runtime的接口调用第三方库

总结:多种解构技术在项目中都会使用,按照具体场景选择解耦最适合的解耦方式

Part3 实施步骤

  1. 公共模块抽离git子模块,并用pod管理。包括共用组件、UI控件、公共方法等
  2. 引入PHIEngine,使appdelegate瘦身,同时抽离基础组件
  3. 引入serviceProtocol,用协议解耦组件
  4. 引入PHIRoute,做事件路由
  5. 引入Runtime 解耦技术
  6. 重新梳理代码目录结构
  7. 开发配置组件,把业务需要的配置抽到配置层
  8. 把组件化方案同步到其他业务线

总结:重构完成后的代码结构会较为清晰,各个基础组件也可单独维护和使用,基础组件的更换不会影响到业务层的开发,代码复用性加强,各个业务线可用一套基础组件

Part4 其他

工程组件化的目的不仅是为了目前组件的复用,也是为以后新组件开发打好基础

a)debugger组件开发

  • 给测试和联调用户使用
  • 查询日志
  • 切换网络环境

b)性能监听组件开发

  • 性能检测
  • 网络检测

参考资料:
podSpec语法 https://guides.cocoapods.org/syntax/podspec.html

CATALOG
  1. 1. 前言
  2. 2. 组件化的目标:
  3. 3. Part1 目前代码结构中的问题
  4. 4. Part2 组件化方案
    1. 4.1. 一、Pod代码管理技术
    2. 4.2. 二、组件协议解耦技术 (PHIServiceManager)
    3. 4.3. 三、App路由解耦技术 (PHIRoute)
    4. 4.4. 四、Runtime解耦技术(PHIMediator)
  5. 5. Part3 实施步骤
  6. 6. Part4 其他