代码之家  ›  专栏  ›  技术社区  ›  ant2009

将类映射到一起时处理类中空类型的最佳实践

  •  0
  • ant2009  · 技术社区  · 7 年前

    我用的是Kotlin 1.30。我有以下将从API填充的实体类。有些属性可能是API中的空值,所以我已经使用安全的空值类型声明了它们。

    但是,我将把这个实体类映射到我的域模型类。想知道处理空类型的最佳方法是什么?

    我有两个关于如何在绘制班级地图时做到这一点的想法。

    1. 将所有等效属性声明为安全的空类型
    2. 使用elivs运算符返回空字符串或空列表

    在下面的片段中,我使用的是ELVIS运算符。只是想知道这方面的最佳实践是什么?

    class LoginResponseDomainMapperImp : LoginResponseDomainMapper {
        override fun map(entity: LoginResponseEntity): LoginResponse {
            return LoginResponse(
                entity.token ?: "",
                mapUsers(entity.user),
                mapEnterprises(entity.enterprises ?: emptyList()),
                mapVendors(entity.vendors ?: emptyList()))
        }
    
        private fun mapUsers(userEntity: UserEntity?): User {
            return User(
                userEntity?.id,
                userEntity?.email,
                userEntity?.firstName,
                userEntity?.lastName,
                userEntity?.phone,
                userEntity?.address,
                userEntity?.dob,
                userEntity?.customer,
                userEntity?.enterpriseIds ?: emptyList(),
                userEntity?.vendorIds ?: emptyList())
        }
    
        private fun mapEnterprises(enterprisesEntity: List<EnterprisesEntity>): List<Enterprises> {
            val enterpriseList = mutableListOf<Enterprises>()
    
            enterprisesEntity.forEach {
                val enterprise = Enterprises(
                    it.id,
                    it.enterpriseName,
                    it.typeLabel,
                    it.country,
                    it.imageId,
                    it.managers,
                    it.members,
                    it.stripe,
                    it.locations)
    
                enterpriseList.add(enterprise)
            }
    
            return enterpriseList.toList()
        }
    
        private fun mapVendors(vendorsEntity: List<VendorsEntity>): List<Vendors> {
            val vendorList = mutableListOf<Vendors>()
    
            vendorsEntity.forEach {
                val vendor = Vendors(
                    it.id,
                    it.vendorName,
                    it.typeLabel,
                    it.userRole,
                    it.latitude,
                    it.longitude,
                    it.partner,
                    it.country,
                    it.imageId,
                    it.stripe)
    
                vendorList.add(vendor)
            }
    
            return vendorList.toList()
        }
    }
    

    将从API填充的实体类,因此其中任何一个都可以为空

    data class LoginResponseEntity(
        @SerializedName("token") val token: String?,
        @SerializedName("user") val user: UserEntity?,
        @SerializedName("enterprises") val enterprises: List<EnterprisesEntity>?,
        @SerializedName("vendors") val vendors: List<VendorsEntity>?)
    
    data class UserEntity(
        @SerializedName("id") val id: String?,
        @SerializedName("email") val email: String?,
        @SerializedName("first_name") val firstName: String?,
        @SerializedName("last_name") val lastName: String?,
        @SerializedName("phone") val phone: String?,
        @SerializedName("address") val address: String?,
        @SerializedName("dob") val dob: String?,
        @SerializedName("customer") val customer: String?,
        @SerializedName("enterprise_ids") val enterpriseIds: List<String>?,
        @SerializedName("vendor_ids") val vendorIds: List<String>?)
    
    data class EnterprisesEntity(
        @SerializedName("id") val id: String?,
        @SerializedName("enterprise_name") val enterpriseName: String?,
        @SerializedName("type_label") val typeLabel: String?,
        @SerializedName("referral_code") val referralCode: String?,
        @SerializedName("country") val country: String?,
        @SerializedName("image_id") val imageId: String?,
        @SerializedName("managers") val managers: List<String>?,
        @SerializedName("members") val members: List<String>?,
        @SerializedName("stripe") val stripe: Boolean,
        @SerializedName("locations") val locations: List<String>?)
    
    data class VendorsEntity(
        @SerializedName("id") val id: String?,
        @SerializedName("vendor_name") val vendorName: String?,
        @SerializedName("type_label") val typeLabel: String?,
        @SerializedName("user_role") val userRole: String?,
        @SerializedName("latitude") val latitude: Float,
        @SerializedName("longitude") val longitude: Float,
        @SerializedName("partner") val partner: Boolean,
        @SerializedName("country") val country: String?,
        @SerializedName("image_id") val imageId: String?,
        @SerializedName("stripe") val stripe: Boolean)
    

    数据模型类在域中,最好声明它们都是安全的空类型?

    data class LoginResponse(
        val token: String,
        val user: User?,
        val enterprises: List<Enterprises>,
        val vendors: List<Vendors>)
    
    data class User(
        val id: String?,
        val email: String?,
        val firstName: String?,
        val lastName: String?,
        val phone: String?,
        val address: String?,
        val dob: String?,
        val customer: String?,
        val enterpriseIds: List<String>,
        val vendorIds: List<String>)
    
    data class Enterprises(
        val id: String,
        val enterpriseName: String,
        val typeLabel: String,
        val country: String,
        val imageId: String,
        val managers: List<String>,
        val members: List<String>,
        val stripe: Boolean,
        val locations: List<String>)
    
    data class Vendors(
        val id: String,
        val vendorName: String,
        val typeLabel: String?,
        val userRole: String,
        val latitude: Float,
        val longitude: Float,
        val partner: Boolean,
        val country: String?,
        val imageId: String,
        val stripe: Boolean)
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Willi Mentzel user670265    7 年前

    首先,在Kotlin中没有安全的空类型。变量是否可以为空。

    如果API通过缺少或明确设置空值来传递空值,则数据类应以这些变量可以为空的方式反映这些值(问号 ? 数据类型之后)。

    当您将这些数据类映射到您的实体(域模型)时,您应该正确地处理空的大小写。由于这是一个有效的情况,即API提供您所期望的空值,所以您应该通过分配一个默认值来处理这种情况。

    使用elvis运算符只是优雅地处理可空类型的一种方法,但是如果使用它,仍然是您的选择。

        2
  •  1
  •   Omar Mainegra    7 年前

    如果将所有属性声明为 nullable 那不比 Java ,即使您使用空的安全操作员访问它们。如果您的JSON属性 null 价值,这意味着在您的业务逻辑中,它们并不总是有价值的,并且您有责任通过回退到默认值(即 emptyList() "" 或者更复杂的事情,比如重定向到登录屏幕。