在干净的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
?
我正在尝试找到切实可行的答案,人们如何解决这种问题,而不是最终编写大量的数据类和映射器?
答案 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模型。
但是,在某些情况下,数据模型(实体)包含表示层不需要的信息。在那里,您需要在域和表示层中使用不同的模型。不要传递不需要的信息!