Skip to main content

组件化架构设计

背景

近年来,组件化一直是业界积极探索和实践的方向,越来越多的公司使用组件化来构建项目,我们公司在组件化实践方向也有了一些实践,但目前还没有一个标准,这也是我们为什么要整理这个文档的目的,确定一下组件化的方案,为未来的复杂业务助力。

组件化带来的优势

首先组件化的一些优势是我们应用它的核心价值,那么都有哪些优势呢?大致总结如下:

  1. 加快项目编译速度,提高开发效率,因为模块可以独立编译、测试、打包和部署
  2. 提高组件的复用
  3. 避免了模块之间的交叉依赖,做到低耦合、高内聚
  4. 引用的第三方库代码统一管理,避免版本不统一,减少引入冗余库

组件化目标

首先设立一个目标,来保证我们后续不偏离方向,不能为了组件化而组件化,复杂的设计必定会造成大量的学习成本,反而会降低开发效率,其实我们设计组件化的初衷也是为了能更加简单化,而且目标促使我们价值观统一,大家朝一个方向努力,共同创造价值。 如下:

  1. 生成组件化模版项目,能够快速的迭代新项目
  2. 组件化脚手架,可定制化

组件化规范

1.代码尽可能的解耦
对项目进行模块拆分,模块分为两种类型,一种是功能组件模块,封装一些公共的方法服务等,作为依赖库对外提供;另一种是业务组件模块,专门处理业务逻辑等功能,这些业务组件模块最终负责组装APP。

2.每个组件都可单独运行

  • 每个组件都是高度内聚的,是一个完整的整体
  • 通过 Gradle脚本配置方式,进行不同环境切换

3.组件间通信
通过路由的方式进行通信(路由框架待选择)

4.规范组件生命周期
生命周期指的是组件在应用中存在的时间,组件是否可以做到按需、动态使用、因此就会涉及到组件加载、卸载等

5.严格限制公共基础组件的增长
随着开发不断进行,要注意不要往基础公共组件加入太多内容。而是应该减小体积!倘若是基础组件过于庞大,那么运行组件也是比较缓慢的

组件化常见问题以及解决方案

  1. 通信
    通信这个需要考虑两个方面,一个是同进程之间,一个是跨进程之间,那么就会有两种解决方案如下:
    同进程:接口依赖调用
    跨进程:Andromeda Andromeda提供了接口式的组件间通信管理,包括同进程的本地接口调用和跨进程接口调用。

  2. 初始化
    app-startup google官方
    AppInit AppInit 用于解决美团收银 B 端 App 在业务演进过程中的实际问题

  3. 代码隔离,如何处理依赖关系
    这里推荐美团的组件化方案:把每个业务组件都拆分成了一个Export Module和Implement Module。这样的话,如果Module A需要调用Module B提供的接口,同时Module B需要调用Module A的接口,只需要Module A依赖Module B Export,Module B依赖Module A Export就可以了。

  4. 页面跳转
    ARouter
    Navigation Navigation这里单独拿出来讲一下,其实在用到Navigation时有很多好处,如下:
    (1)可以实现单Activity+多Fragment架构,好处就在于Fragment比Activity更轻量级,从而减少内存占用,其实Activity与Activity之间存在进程通信以及其他开销。
    (2)结合Flutter这种框架,我们发现,它的一个页面由多个Widget组成,页面更加灵活,同样的Fragment也是一样,它需要放在Activity中,且灵活可配。
    (3)官方支持,放心使用

Navigation 组件化项目:android-modular-architecture

组件化架构图设计

components-ac.png 以上设计图,遵循组件化规范。详细介绍请往下看。

模块介绍

  1. 业务组件,主要是能否独立业务的组件,如登陆模块可以抽离出一个完整的组件,并可以打包出独立的app包。
  2. 功能组件
    • Common:包含公共业务接口定义,数据模型,数据库相关。• 自定义View:一些特殊样式,或者组合使用的自定义View
    • 日志:日志框架组件,如logan
    • 推送:push消息等组件,独立于业务• 分享:分享SDK
    • 视频:视频相关功能组件• 即时通讯:聊天实时消息相关组件
  3. Core基础层
  4. 网络请求(采用 Retrofit+协程)
  5. 图片加载(策略模式,Glide 与 Picasso或者coil 之间可以切换)
  6. 基类 Adapter 的封装(支持 item动画、多布局item、下拉和加载更多、item点击事件)
  7. 通用的工具类,Kotlin版本的动态扩展(Context、Fragment、Activity、Service、Intent等)
  8. 协程封装
  9. 其他等等
  10. BuildSrc + Composite Builds Module
    BuildSrc的运用更好的Gradle依赖关系管理,Composite Builds提升构建速度,编写自定义插件。且统一管理框架版本信息,防止组件之间框架依赖版本冲突问题

组件化脚手架介绍

首先说下为什么要设计脚手架,这个源于SpringBoot脚手架的灵感,因为组件化后,项目各个模块相对独立,如果我们开发新项目就会遇到各种各样的功能,且符合我们的实际场景需求,如: 咨询师没有数据库,而其他app都需要数据库存储。小猫大部分是离线处理,而ESA又都是后台处理,每个业务都有不同的特点,所以我们想做一个可定制化的组件化项目,而不是一成不变。 脚手架的开发也是我们设计的一个目标,设计如下: scaffold-01.png scaffold-02.png 此脚手架我们做的是在线的,傻瓜式操作,只需要在页面中选择已经配置好的模版,可定制如下:

  1. 包名
  2. 语言
  3. 最低兼容版本
  4. 架构选择
  5. 组件依赖

当然这个页面的设计还不够完善,没有体现可以依赖三方框架,这个我们也会在未来的设计中加入进去,结合我们公司实际的业务场景,来做到定制化生成。

讨论结论

目前待确认框架选型如下:

  1. 不使用单Activity+多Fragment架构(此点考虑到C端已经在用多Activity,且单Activity并没有更好的实践结果,所以保持原有架构)
  2. 数据库考虑升级为moshi,或者kotlin官方serialization,去除Gson逻辑,后续专门做专题讨论
  3. 网络层抛弃Rxjava方式,未来用okhttp+协程方式,后续专门做专题讨论
  4. 页面跳转依然适用Arouter
  5. 组件初始化目前有贤论大佬自开发方案和google官方或美团相关方案,待后续专门专题讨论
  6. gradle build方式更新为 kotlin dsl gradle

参考项目

JetpackMvvm
MVVMHabitComponent
AndroidProject
sunflower
Jetpack-MVVM-Best-Practice
Pokedex
android-modular-architecture
MVVM-Architecture