多模块不是银弹,但在中大型 Flutter 项目里,它往往是维持工程健康的必要条件。本文从“为什么拆、怎么拆、拆到什么粒度”三个维度,给出一套可落地的模块化实践。
1. 什么时候需要模块化?
以下信号出现 2 个以上,就应该考虑模块拆分:
- 编译/热重载明显变慢
- 业务功能线越来越多,依赖交织
- UI 与业务逻辑混在一起,改动牵一发而动全身
- 多人协作冲突频繁
模块化的目标不是“优雅”,而是降低耦合成本。
2. 模块边界:以“业务能力”而不是“页面”划分
常见误区是按页面拆模块,这会导致:
- 组件复用困难
- 业务逻辑分散
- 模块之间强耦合
更稳妥的方式是按“业务能力”拆:
- 用户体系模块(登录、权限、个人信息)
- 内容模块(列表、详情、发布)
- 交易模块(订单、支付、钱包)
- 基础能力模块(网络、存储、日志、埋点)
这样拆出来的模块有清晰边界,彼此依赖更少。
3. 分层:把“业务”与“基础能力”分开
推荐三层结构:
- Core 层:网络、缓存、日志、路由、配置
- Feature 层:业务模块(用户、内容、交易)
- UI 层:纯展示与交互
关键原则:
- Feature 只能依赖 Core,不依赖其他 Feature
- UI 只依赖 Feature,不直接依赖 Core
这能避免“循环依赖”和“依赖爆炸”。
4. 依赖治理:让依赖“单向流动”
工程化里最难的是依赖治理,建议引入以下规则:
- 统一依赖注入入口(如 AppContainer / ServiceLocator)
- 禁止 Feature 相互直接引用
- 共享能力抽到 Core 或 Common 模块
示意:
app/
core/
features/
user/
content/
commerce/
ui/
5. 模块通信:事件流优先,直连最少
模块之间的通信不要随便互调,建议:
- 通过事件总线 / 状态流同步
- 必要时定义接口(抽象协议)
- 避免“跨模块直接调用实现类”
这能让模块更独立,也更易测试。
6. 版本与发布:把“模块化”变成可复用资产
当模块稳定后,可以尝试:
- 把模块独立成包(Package)
- 内部 Git 仓库管理
- 版本化发布,支持多项目复用
这是中大型团队提升工程复用率的关键一步。
7. 模块化落地清单
- 明确模块边界(业务能力)
- 分离 Core / Feature / UI
- 依赖单向流动
- 模块通信抽象化
- 统一 DI 入口
- 减少跨模块直接调用
总结
Flutter 的模块化不是为了“拆得多”,而是为了让团队在复杂度中保持可控:边界清晰、依赖收敛、协作顺畅。当工程规模提升时,模块化不是“可选项”,而是工程可持续发展的基础。