干净的架构:在不同的层共享相同的模型/实体

时间:2018-11-27 21:32:22

标签: android kotlin architecture clean-architecture

在干净的Android应用程序设置中,我对每一层(数据,域,表示形式)都有自己的Gradle模块。我还为每个图层都有自己的模型/实体,可以使用映射器将它们从一层转换为另一层。这导致我有很多kotlin数据类,它们表示基本相同的东西,但位于不同的层。这听起来不对我。

简单的例子:

数据层-Android库模块

@JsonClass(generateAdapter = true)
data class BuildingEntity(
    @Json(name = "u_id")
    val id: String,

    val name: String,

    val latitude: Double,

    val longitude: Double,

    @Json(name = "current_tenants")
    val tenants: List<TenantEntity>? = null
)

域层-纯Kotlin模块

data class Building(

    val id: String,

    val name: String,

    val location: CoordinatePoint,

    val tenants: List<Tenant>? = null

演示层 Android应用模块

data class BuildingModel(

    val id: String,

    val name: String,

    val location: LatLng,

    val tenants: List<TenantModel> = listOf()
)

BuildingEntity是从外部网络api获取的。

这很好地将每个模块彼此分离,但是在我的应用程序中,我有很多具有嵌套结构的不同实体。因此,我最终编写了很多kotlin数据类和映射器。

我该如何简化?我可以删除Building类并在数据和域层上使用BuildingEntity吗?只需在表示层将BuildingEntity转换为BuildingModel

我正在尝试找到切实可行的答案,人们如何解决这种问题,而不是最终编写大量的数据类和映射器?

3 个答案:

答案 0 :(得分:2)

在我的域模块中,我将模型作为接口(Kotlin允许我们在接口内部具有val),数据模块中的实现以及表示中根本没有模型。

看看这个小样本:

域:

interface IUserModel {
    val id: String
    val name: String
}

interface UserRepository {
    fun getUserDetails(id: String): IUserModel
}

数据:

@Entity
data class UserEntity(
    @SerializedName("userId")
    override val id: String,
    override val name: String
) : IUserModel

class UserRepositoryImpl(val userDao: UserDao) : UserRepository {

    override fun getUserDetails(id: String): IUserModel {
        return userDao.getUser(id) //userDao.getUser returns a UserEntity
    }
}

演示:

class UserDetailsViewModel(val userId: String, val userRepository: UserRepository) : ViewModel() {
    val userData: LiveData<IUserModel> = MutableLiveData()
    fun getUserData() {
        (userData as MutableLiveData).postValue(userRepository.getUserDetails(userId))
    }
}

没有映射器,没有大量的数据类。

我有几个具有此结构的项目,有时需要一个映射器(将网络模型转换为数据库实体),但是使用接口作为域中的模型可以大大减少冗长程度。

答案 1 :(得分:2)

实际上,这是正确的做法。为了使应用程序完全干净,您应该在每一层中对实体进行不同的表示,然后使用映射器进行转换。这样,您仅在需要更改某些实体时才更改映射器。

例如,您可能从服务器接收到一些不想在UI中显示的数据,因此您的演示文稿实体中没有这些数据。另一个示例是,如果您想更改数据实体中的参数名称。如果直接从演示文稿访问它,则需要更改所有访问权限。相反,如果您有映射器,则唯一要做的就是更改映射器。

很明显,清洁架构是一个复杂的架构,在大型项目和长期项目中会更有意义,因为变更项目可能会更频繁地出现。因此,如果您正在做一个小应用程序,而又想摆脱很多代码,那就没关系了。在这种情况下,我会建议您为Domain和Presentation使用相同的实体,并为数据对象保留映射器,因为数据依赖于API,因此更改并不取决于您,并且您将从映射器中受益。 / p>

答案 2 :(得分:0)

我知道这是一个老问题,但是我想贡献一点。

所以,是的,这本书是干净的体系结构。如果您想“破坏”体系结构,那么我建议您删除Presentation Models,而使用Domain模型。

但是,在某些情况下,数据模型(实体)包含表示层不需要的信息。在那里,您需要在域和表示层中使用不同的模型。不要传递不需要的信息!