首页 > 解决方案 > 为什么我不能将领域层中的类设置为具有清洁架构的抽象类?

问题描述

我正在使用artical学习 Clean Architecture 。

我知道域层是洋葱最内部的部分(不依赖于其他层),它包含实体、用例和存储库接口。

我认为我应该在域布局的用例中使用抽象类或接口,您可以在上面的文章中看到图 1。

图 1 在此处输入图像描述

以下代码来自项目https://github.com/igorwojda/android-showcase

internal class GetAlbumListUseCase域层中,您可以看到图 2。

我认为GetAlbumListUseCase应该是抽象类。

但是当我将其替换internal abstract class GetAlbumListUseCase(...).

1:我怎么了?它是否在 Kodein 期间由 AlbumDomainModule.kt 引起?

2:我应该在域布局的用例中使用抽象类还是接口?

GetAlbumListUseCase.kt

internal class GetAlbumListUseCase(
    private val albumRepository: AlbumRepository
) {

    sealed class Result {
        data class Success(val data: List<Album>) : Result()
        data class Error(val e: Throwable) : Result()
    }

    suspend fun execute(): Result {
        // Due to API limitations search with custom phrase have to be performed to get albums
        val phrase = "Jackson"

        return try {
            Result.Success(albumRepository.searchAlbum(phrase).filter { it.getDefaultImageUrl() != null })
        } catch (e: IOException) {
            Result.Error(e)
        }
    }
}

专辑DomainModule.kt

internal val domainModule = Kodein.Module("${MODULE_NAME}DomainModule") {

    bind() from singleton { GetAlbumListUseCase(instance()) }

    bind() from singleton { GetAlbumUseCase(instance()) }
}

图 2

在此处输入图像描述

标签: kotlinclean-architecture

解决方案


你不能实例化一个抽象类,因为它是……嗯,抽象的。

您误解了我们应该使用抽象的含义。您的组件应该依赖于抽象(最好是接口,而不是抽象类),但您仍然需要提供实现(普通,而不是抽象类)。为此,请将现有类拆分为接口 + 其实现,在配置 DI 时使用实现,并在其他任何地方使用接口。

例如,重命名您的GetAlbumListUseCaseinto ,使用其 APIGetAlbumListUseCaseImpl创建一个接口(在 IntelliJ 中,您可以使用重构 -> 提取接口)并 make implement 。然后在代码中的任何地方使用,但使用. 这与您链接的文章中的内容完全相同。GetAlbumListUseCaseGetAlbumListUseCaseImplGetAlbumListUseCaseGetAlbumListUseCaseGetAlbumListUseCaseImplPostRepositoryPostRepositoryImpl

使用这样的架构,您可以在未来创建替代实现GetAlbumListUseCase并顺利切换它们。您甚至可以同时使用多个实现,例如不同的对象使用不同的实现GetAlbumListUseCase。请注意,在您当前的架构中,所有对象都直接依赖于特定的实现,因此切换到另一个需要修改一半的代码。


推荐阅读