1. MVVM 为何依然主流?它的“崩塌点”在哪里?
MVVM 的流行得益于它与 Android 生命周期组件的完美契合。但在现实压力下,ViewModel 往往沦为代码垃圾场:网络请求、数据库访问、逻辑映射甚至导航决策全都塞了进去。
MVVM 的失败通常不是模式本身的错,而是团队将 ViewModel 当成了“万能层”。资深开发应将业务规则下沉到 Use Case,将数据逻辑推向 Repository,让 ViewModel 回归其本质——UI 状态的协调者。
2. 什么是“真正的”洁净架构(Clean Architecture)?
洁净架构不仅仅是创建名为 data、domain、presentation 的文件夹。
核心准则:依赖方向。内层必须独立于外层。Domain 层不应知道数据来自 Retrofit 还是 Room,甚至不应包含任何 Android 框架类。它是业务规则最纯粹的体现。
3. 现代 Android 应用中,业务逻辑到底该放哪?
放在 Activity 或 Fragment 是初级做法,全部塞进 ViewModel 是中级做法。
正确方案:引入 Use Cases 或 Interactors。每个类代表一个独立的业务操作(如 CalculateShippingCostUseCase)。如果 Android 框架明天消失了,你的业务逻辑依然能自洽运行,那它才算放对了地方。
4. 何时该从单模块转向多模块架构?
过早的模块化是“万恶之源”。
判断标准:模块化是为了解决瓶颈。当构建时间过长、团队协作发生冲突或功能所有权模糊时,才是拆分的时机。架构决策从不是为了追求理论上的“完美”,而是为了解决当下的工程痛点。
5. Repository 层的真实职责是什么?
如果 Repository 只是简单地转发 API 调用,那它根本没必要存在。
它是决策者。它决定数据是从缓存、网络还是本地读取;它负责组合多个数据源,并向上层提供一致的接口。ViewModel 不关心数据怎么来,它只观察输出。
6. Jetpack Compose 如何重构了我们的架构思维?
Compose 将 UI 开发从“指令式”变成了“声明式”。
**状态管理(State Management)成为了架构的核心。UI 是状态的函数。资深开发会定义单一的状态对象,通过单向数据流(UDF)**确保 UI 的可预测性:事件向上流动,状态向下传递。
7. 2026 年,该选 Flow 还是 LiveData?
虽然 LiveData 功勋卓著,但 Kotlin Flow 才是现在的标准。
理由:Flow 与协程无缝集成,支持丰富的变换操作符,且不依赖 Android 生命周期(更适合 Domain 和 Data 层)。在 UI 边界,我们通过生命周期感知的收集器(如 collectAsStateWithLifecycle)来确保安全。
8. 如何防止 ViewModel 变得过于臃肿?
ViewModel 像磁铁一样吸引职责。
治理方案:主动向外推送逻辑。复杂的计算去 Use Case,映射逻辑去 Mapper 类,数据组合去 Repository。健康的 ViewModel 读起来应该像一个状态协调手册,而不是一个后端微服务。
9. 大型应用中,导航逻辑该如何构建?
直接在 ViewModel 中硬编码 Fragment 或路径跳转会导致强耦合。
高级做法:从 ViewModel 发出“导航意图(Intent)”,由 UI 层或专门的 Coordinator/Navigator 来解析并执行跳转。这使得导航逻辑变得可测试,并解耦了业务逻辑与 UI 目的地。
10. 如何处理 DI(依赖注入)而不被框架反噬?
Hilt 等框架很方便,但也容易让依赖关系跨越边界。
原则:将 DI 框架视为接线工具。架构设计应先行,领域层依赖接口而非实现。如果更换 DI 框架需要重构整个业务逻辑,说明你的架构与框架耦合太深了。
11. 离线优先(Offline-first)架构的设计要点?
离线支持不是后期补丁。
实现:缓存逻辑应封装在 Repository 内部。Repository 暴露一个 Flow,立即发射缓存数据,同时在后台静默更新网络数据。UI 只需要对状态做出反应,无需关心数据源。
12. 错误处理:异常应该如何在层级间传播?
直接抛出 IOException 到 UI 层是极不专业的。
做法:将技术异常转换为领域错误模型。Data 层捕获底层错误,转换为 DomainError(如 NetworkUnavailable),ViewModel 再将其映射为用户友好的 UI 消息。让每一层都说自己的“语言”。
13. 领域层(Domain Layer)真的总是必要的吗?
不一定。引入领域层会增加间接成本。
当业务规则复杂、被多个功能共享、或者需要独立于 Android 进行高强度测试时,它才有价值。优秀的架构应随产品演进,而不是在第一天就设计过度。
14. 如何确保架构从一开始就支持测试?
测试的难度反映了架构的质量。
自检:如果写一个单元测试需要 mock 半个 Android 框架,那说明边界设计失败了。资深架构通过隔离纯 Kotlin 逻辑和接口抽象,确保测试运行快速且可靠。
15. 当今 Android 团队最常犯的架构错误是什么?
为了模式而模式。
痛点:盲目照搬洁净架构图纸,强行增加抽象层和模块,结果导致开发速度极慢。最好的架构不是层级最多的,而是职责划分最清晰、且团队易于理解的。 资深开发者优化的是清晰度和可维护性,而不是模式的复杂程度。
结语
架构的艺术在于权衡。我们不需要只会画架构图的“理论家”,我们需要的是能在抽象与效率之间找到那个微妙平衡点的“实干家