为什么 Clean Architectures 通常会在 Repository 和 DataSoruce 之间拆分实现?

Why do Clean Architectures typically split the implementation between Repository and DataSoruce?

提问人:H.Kim 提问时间:11/14/2023 最后编辑:H.Kim 更新时间:11/22/2023 访问量:62

问:

在大多数演示 Clean Architecture 的示例中,存储库的实现和实际接口(与包含其数据的存储库通信)在依赖关系中是分开的,如下面的代码所示。

// Retrofit
interface MyApi {
   @GET("somePath")
   fun getSome() : SomeResponse
}

// Room
@Dao
interface MyDao {
   @Query("select * from mytable")
   fun getSome() : List<SomeEntity>
}

// 1. This is how most examples describe the configuration of a repository.
interface RemoteDataSource {
   fun getSome() : SomeResponse
}
interface LocalDataSource {
   fun getSome() : List<SomeEntity>
}

// instance inject by hilt
class RemoteDataSourceImpl @Inject constructor(private val api : MyApi) : RemoteDataSource {
    override fun getSome() = api.getSome()
}

// instance inject by hilt
class LocalDataSourceImpl @Inject constructor(private val dao : MyDao) : LocalDataSource {
    override fun getSome() = dao.getSome()
}

// instance inject by hilt
class MyRepositoryImpl @Inject (private val remote : RemoteDataSource, private val local : LocalDataSource) : MyRepository {
   override mySomeGetFunction() {
      return MySomeEntity(entity1 = remote.getSome().data, entity2 = local.getSome().data)
   }
}


// 2. why not inline???
// instance inject by hilt
class MyRepositoryImpl @Inject (private val api : MyApi, private val dao : MyDao) : MyRepository {
   override mySomeGetFunction() {
      return MySomeEntity(entity1 = api.getSome().data, entity2 = dao.getSome().data)
   }
}

它们已经是接口了。尽管它们是弱依赖类型,其注入可以根据构建风格随意交换,但许多示例再次将它们包装为 DataSource,并在其实现中简单地绕过它们。

这样做有什么前期原因吗?我试图找到很多参考资料,但我没有看到任何关于 Repository 和 DataSource 的信息。

Android Kotlin 清理架构

评论

0赞 Mohammad Fallah 11/14/2023
我想你没有问清楚你的问题。在你的一些句子中,你使用了“Repository”这个词,而不是“DataSource”。请仔细查看您的问题并对其进行编辑,然后我会尽力帮助您找到答案。
0赞 H.Kim 11/15/2023
@MohammadFallah我认为问题的标题是错误的,所以我编辑了它。

答:

0赞 hatem87 11/22/2023 #1

我认为在某些概念的层面上存在误解,或者可能是问题不太清楚。

存储库是一种模式,用于在大多数时间与数据库中的外部数据源进行交互。 它不依赖于干净的架构。 我建议检查这个问题,我在这里描述了更多关于存储库的优缺点 干净的架构和存储库

从 vue 的 Clean Architecture 角度来看: 您需要分离项目的任何依赖关系,并尽可能减少其更改对设计的影响。 大多数情况下,这些依赖项是外部源,例如:

  • 您的数据库:(输入依赖关系) 在这里,您可以使用存储库与它进行交互,也可以使用其他模式,例如纯数据层... 最重要的是,你的项目应该只识别这个例程的接口,而不是实现。 您需要对仅依赖于 IClientRepository 的域/业务层进行建模,而不查看或了解 ClientRepository 实现。

  • 一个 Api:我们可以在这里有两种情况:

    • 您将使用的 API(输入依赖项)。它就像与数据库交互的图层。它将不是数据库连接,而是 http 连接...

    • 您将公开的 Api(输出依赖项)

  • 还有其他依赖项,例如框架。我将在这里绕过它们。

因此,您的核心领域/项目将成为您设计的内核。

它与表示输入依赖项的许多接互(域使用依赖项接口,如 IClientRepository 或 IPaymentApiClient)。

它还公开了输出依赖项的接口(您的 Api 通过使用其接口公开了领域功能,大多数时候我们称此层为应用程序层)。

不要犹豫,写评论以获得更多澄清。