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

Android中ViewModel传递UseCase:具体类与接口方案选型问询

Android Clean架构中ViewModel传递UseCase的两种方案选择

在Clean架构中,核心层是承载业务逻辑的UseCase层。在Android开发中,我们通常会将UseCase作为构造函数参数传递给ViewModel,示例代码如下:

class AddNoteUseCase(noteRepository: INoteRepository) : IUseCase {
    override fun invoke(note: Note) {
        noteRepository.addNote(note)
    }
}

目前存在两种向ViewModel传递UseCase的实现方式:

1. UseCase与ViewModel紧耦合

class NoteViewModel(addNoteUseCase: AddNoteUseCase) {
    // 使用UseCase的业务代码
}

这种方案的问题很明显:无法伪造UseCase实例,导致ViewModel的单元测试难以隔离依赖;同时后续如果需要替换或扩展AddNoteUseCase的实现,ViewModel代码也必须跟着修改,不利于长期迭代。

2. UseCase与ViewModel松耦合

class NoteViewModel(addNoteUseCase: IUseCase) {
    // 使用UseCase的业务代码
}

这种方案通过依赖抽象接口IUseCase,支持伪造实例来完成ViewModel的单元测试,同时也更符合架构的扩展性要求。

哪种方案更实用?

针对这个问题存在两种不同观点:

  • 观点一:UseCase仅包含单个方法,没必要伪造,直接依赖具体类更简单。
  • 观点二:不伪造UseCase的话,无法完成相关测试。

实际开发中,松耦合方案更值得推荐,原因如下:

  1. 单元测试隔离性:ViewModel的单元测试核心是验证自身逻辑,而非UseCase的内部实现。通过伪造IUseCase,我们可以精准测试ViewModel是否在正确的时机、传入正确的参数调用了UseCase,完全不受UseCase依赖的Repository或其他组件影响,测试结果更可靠。
  2. 业务扩展性:当前的UseCase可能只有单个invoke方法,但随着业务迭代,可能需要添加新方法,或者替换成其他实现(比如新增一个带缓存逻辑的AddNoteUseCase)。松耦合的方式让ViewModel无需修改任何代码就能适配这些变化,符合开闭原则。
  3. 契合Clean架构思想:Clean架构的核心原则之一是“依赖抽象,而非具体实现”,松耦合方案正是这一原则的落地,能让各层职责边界更清晰,代码的可维护性和可读性更强。

另外需要明确:UseCase本身的测试应该单独进行,测试时依赖其下层的抽象(比如示例中的INoteRepository)来伪造依赖,而非在ViewModel的测试中验证UseCase逻辑。ViewModel测试只需要确保正确调用了UseCase即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:16:18