一、组件化思想入门:为什么需要组件化?

说实话,我刚入行那会儿,项目结构特别简单。一个 app 模块,里面包罗万象——网络请求、UI 界面、数据存储、业务逻辑,全揉在一起。那时候团队小,人少活多,这么干确实快。

但后来项目越来越大,问题就来了。我记得有一次,我只是改了一个工具类的命名,结果编译花了整整 8 分钟。更崩溃的是,改完以后,三个同事同时找我——「你改的啥?我这边冲突了。」

嗯,这就是典型的「大泥球」架构。所有代码耦合在一起,牵一发而动全身。

1.1 为什么需要组件化?

说白了,组件化就是为了解决大型项目的维护难题。你想想看,一个 App 可能有几十个功能模块,如果全写在一起,会有什么后果?

  • 编译慢:改一行代码,整个项目重新编译。我见过一个项目,全量编译要 15 分钟。
  • 冲突多:多人同时修改同一个文件,Git 合并时天天打架。
  • 测试难:改了一个小功能,回归测试要跑全量,因为不知道影响了哪里。
  • 复用差:同样的登录逻辑,换个项目就得重写一遍。

核心痛点:当项目代码量超过 10 万行时,传统的单体架构会让开发效率断崖式下降。

组件化就是把 App 拆成一个个独立的组件。每个组件可以单独开发、单独测试、单独编译。就像搭积木一样,需要什么功能,就拿对应的组件拼上去。

1.2 组件化与模块化的区别

这个问题我经常被问到。很多人觉得组件化和模块化是一回事,其实不然。

维度 模块化 组件化
粒度 较大,通常是功能模块 较小,通常是独立业务单元
独立性 逻辑独立,但编译仍在一起 完全独立,可单独编译运行
依赖关系 模块间可以互相依赖 组件间通过接口通信,无直接依赖
复用范围 通常只在当前项目复用 可跨项目、跨团队复用
测试方式 需要集成到主工程测试 可独立运行测试

举个例子你就明白了。模块化就像把一个大房间分成客厅、卧室、厨房——它们功能不同,但共用同一个水电系统。而组件化就像预制板房——每块墙板都是独立生产的,拉到工地直接拼装。

我的经验:模块化是组件化的基础。我建议团队先做好模块化拆分,再逐步过渡到组件化。一步到位容易翻车。

1.3 组件化架构概览

一个典型的组件化架构,从上到下大概分四层。我画个图给你看:

┌─────────────────────────────────────┐
│            App 壳工程                 │
│  (负责组装组件,不包含业务逻辑)        │
├─────────────────────────────────────┤
│         业务组件层                    │
│  ┌──────┐ ┌──────┐ ┌──────┐        │
│  │ 首页  │ │ 发现  │ │ 我的  │  ...  │
│  └──────┘ └──────┘ └──────┘        │
├─────────────────────────────────────┤
│         功能组件层                    │
│  ┌──────┐ ┌──────┐ ┌──────┐        │
│  │ 网络  │ │ 图片  │ │ 路由  │  ...  │
│  └──────┘ └──────┘ └──────┘        │
├─────────────────────────────────────┤
│         基础组件层                    │
│  ┌──────┐ ┌──────┐ ┌──────┐        │
│  │ 工具  │ │ 日志  │ │ 存储  │  ...  │
│  └──────┘ └──────┘ └──────┘        │
└─────────────────────────────────────┘

这四层各有各的职责:

  • App 壳工程:就是个空壳子,负责把各个组件组装起来。它不写任何业务代码。
  • 业务组件层:每个业务组件对应一个独立功能。比如首页、购物车、个人中心。它们之间不能直接依赖。
  • 功能组件层:提供通用能力。比如网络请求、图片加载、路由跳转。这些组件可以被多个业务组件共用。
  • 基础组件层:最底层,提供基础工具。比如日志、加密、数据库封装。这一层尽量稳定,少改动。

注意:依赖关系只能从上往下,不能反向依赖。我曾经见过一个项目,基础组件层引用了业务组件层的类——结果一改业务代码,整个基础层都得重新编译。这就是典型的依赖倒置错误。

1.4 组件化的核心原则

做组件化,有几个原则你得记住。这些都是我踩过坑以后总结出来的:

  1. 单一职责:一个组件只做一件事。比如「登录组件」就只负责登录,别把注册、找回密码也塞进去。
  2. 接口隔离:组件之间通过接口通信,不要直接引用对方的类。这样换组件就像换插头一样简单。
  3. 依赖反转:高层组件不依赖低层组件,大家都依赖抽象接口。这是解耦的关键。
  4. 可测试性:每个组件都能独立运行和测试。做不到这一点,组件化的价值就大打折扣。

避坑指南:我曾经把一个组件做得太「万能」,结果它依赖了七八个其他组件。后来想单独测试这个组件,发现根本跑不起来——因为缺少太多依赖。所以,保持组件的独立性,比什么都重要。

1.5 什么时候该上组件化?

不是所有项目都需要组件化。我见过有人写个记账 App 也搞组件化,结果光搭建架构就花了两周,得不偿失。

我个人觉得,出现以下信号时,就该考虑组件化了:

  • 项目代码量超过 20 万行
  • 团队人数超过 10 人
  • 单次全量编译超过 5 分钟
  • 经常出现 Git 冲突
  • 需要同时维护多个 App(比如主 App 和 Lite 版)

如果只是个小项目,老老实实用模块化就够了。别为了技术而技术,这是很多工程师容易犯的毛病。

好了,这一章就聊到这儿。下一章我们开始动手,搭建第一个组件化项目。到时候我会带着你一步步配置 Gradle,把组件跑起来。