【问题标题】:In Clean architecture MVVM where transform objects to adapter?在 Clean architecture MVVM 中,将对象转换为适配器?
【发布时间】:2021-11-19 21:39:10
【问题描述】:

所以,假设我有一个具有多种视图类型的适配器,而我从服务器 api 收到的只是一个列表,我必须在我的适配器对象中进行转换。

示例: 我有一个关联类型的人员列表,让我们考虑 1 和 2,我想在我的回收站视图中显示不同类型之间的标题。

所以,我有一个片段 - 视图模型 - 用例 - 存储库(对 api 的请求)

我的适配器期望一个人的列表。 假设 Person 是一个接口,而 person1 和 person2 实现了它。

最后,我从服务器收到一个包含 PersonApi 对象的列表,这些对象有一个类型作为参数,我必须将其转换为我的适配器对象。

我应该在哪里进行这种转换? 存储库? 用例? 查看模型?

我的猜测,应该是用例。

编辑: 添加了图表

【问题讨论】:

  • 顺便说一句:这是 MVVM 而不是 MVMM。

标签: android mvvm clean-architecture


【解决方案1】:

让我们从这样一个事实开始,即干净架构的完整实现有很多层、模型映射......这使得它难以实现。因此,我们可以利用简化版本,就像您在问题中提到的三层一样; DataDomainPresentation

每个层都有特定的数据模型很好,但也可以将Domain 模型与Presentation 共享。这意味着您只需要一个数据映射步骤,这发生在DataDomain 之间的邻接点。 由于存储库是DataDomain 之间的桥梁,因此它是映射模型的正确位置。

存储库的定义应该是Domain 的一部分,以及Data 内部的实现。这样Data 层提供的正是Domain 层所期望的。请记住,Domain 不得知道Data 层及其实现的任何内容。所以,如果你在不同的 gradle 模块中实现你的层,你应该在 Data 模块中依赖于 Domain,而不是相反。

类的简化实现可能如下所示:

域:

interface Person

class Person1() : Person

class Person2() : Person

interface PersonRepository {
    fun getPersons(): List<Person>
}

class GetPersonsUseCase(val repository: PersonRepository) {
    fun execute(): List<Person> {
        return repository.getPersons()
    }
}

数据:

class PersonRepositoryImpl(val service: PersonService): PersonRepository {
    fun getPersons(): List<Person> {
        val list: List<PersonEntity> = service.getPersons()
        return list.map { it.toPerson() }
    }
}

PersonEntity.toPerson(): Person {
    return ... // create an instance of Person1 or Person2 based on requirements.
}

【讨论】:

  • 只是问,为什么存储库的定义应该在域上?这意味着用例(域)的定义也应该在演示中?
  • 实际上,clean-arch 的目的是将领域(业务逻辑)与其他层隔离。因此,域本身定义了如何与数据或表示进行交互。在数据的情况下,它定义存储库抽象,在表示的情况下,它可以定义交互器。因此,与域相关的所有内容都保留在域内,而不是其他层。您可以在此处找到最佳实践之一:github.com/android10/Android-CleanArchitecture-Kotlin
【解决方案2】:

根据 Clean 架构的基本规则,每一层都完全独立于其他层。所以这里你必须根据场景在模型类或视图模型类中编写业务逻辑,将此唯一属性值发布到视图(适配器)。请在下面找到高级架构图:

【讨论】:

  • 所以你说我必须在用例或视图模型上进行转换?
【解决方案3】:

您可以创建一个映射器类来转换用例中的数据并将域对象返回到您的视图中 more information and sample code

【讨论】:

  • 感谢您的回答,这就是我要做的。但我的问题是,在哪里映射呢?领域?查看型号?两者都有?
  • 在域层你必须这样做,(网络 -> 存储库 -> 域)和域可以看到网络和存储库文件,你的视图/视图模型只能看到域层文件
【解决方案4】:

Use Case 层执行此操作,所有情况下ViewModel 不应更改 API 中的任何数据,它只会将其发送到view

【讨论】:

    【解决方案5】:

    在存储库中,您更改对域实体的响应,在 ViewModel 中,您将域实体更改为查看实体,其中域是控制您的行为的地方,例如您从 API 获取数据,然后呈现在视图层并且您想为将域映射到视图的视图添加某些属性,然后如果您想将事物存储在数据库中,您可以从视图映射到域以及从域映射到数据库实体

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-03
      • 2015-11-19
      • 1970-01-01
      • 2022-11-26
      • 2023-03-11
      • 2022-10-13
      相关资源
      最近更新 更多