You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVP转MVVM重构时多模块循环依赖问题及解决方案咨询

解决MVP转MVVM时的模块循环依赖问题

一、先解决当前循环依赖问题

循环依赖的核心原因是app和features模块互相引用,Gradle无法确定构建顺序,导致任务死锁。可以通过以下方式打破依赖链:

1. 抽离共享代码到独立基础模块

  • 新建base(或common)模块,将两个模块都需要的内容迁移过去:
    • 通用实体类、工具类、常量定义
    • 基础组件:BaseActivity、BaseViewModel、通用布局控件
    • 路由跳转的抽象接口(比如Router接口,定义页面跳转方法)
  • 让app和features模块都依赖base模块,替换原来的双向依赖:
    // app模块的build.gradle
    implementation project(':base')
    implementation project(':features')
    
    // features模块的build.gradle
    implementation project(':base')
    
  • 页面跳转通过base模块的路由接口实现:比如app模块实现路由接口,features模块通过接口调用跳转,避免直接引用app模块的页面类。

2. 调整模块职责,保持单向依赖

  • 明确app作为壳模块:只负责全局初始化(Application)、启动页(SplashActivity),以及集成各业务模块,仅依赖业务模块,不被业务模块依赖。
  • features作为业务模块:包含Login、Main等业务页面及相关逻辑,仅依赖base模块,绝对不依赖app模块。
    • 如果features需要跳转到app模块的页面,要么把目标页面移到features,要么通过base的路由抽象实现跳转。

二、更合理的MVP转MVVM重构方案

1. 先在原模块内完成单页面重构,再拆分模块

不要一开始就拆分模块,先在app模块内完成单个页面的MVP到MVVM转换:

  • 把LoginPresenter的逻辑迁移到LoginViewModel,用LiveData替代Presenter和View的接口回调
  • 验证Login页面的MVVM逻辑跑通后,再逐步迁移其他页面,最后按业务拆分模块,降低重构风险。

2. 按业务域拆分模块,而非单个页面

不要只把Login页面单独拆到模块,而是按业务域划分独立模块:

  • 新建login-feature模块:包含LoginActivity、LoginViewModel、登录相关的Repository、数据源等完整登录业务逻辑
  • 新建main-feature模块:包含MainActivity、MainViewModel及主页相关逻辑
  • app模块作为壳,依赖所有业务模块,业务模块之间通过base模块的事件(比如LiveData事件)或路由接口通信,避免直接依赖。

3. 落地依赖倒置原则

在MVVM重构中,严格遵循依赖倒置:

  • ViewModel不直接持有View引用,通过LiveData向View发送状态更新
  • 模块之间依赖抽象而非具体实现:比如login-feature定义LoginSuccessEvent,app或main-feature监听该事件完成页面跳转,而非login-feature直接引用MainActivity类。

内容的提问来源于stack exchange,提问作者ozanurkan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 21:47:14