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
相关产品推荐
相关产品推荐

