Kotlin 避免重复相同的逻辑

Kotlin 避免重复相同的逻辑,kotlin,coding-style,Kotlin,Coding Style,我有以下数据类: sealed class ExampleDto object Type1ExampleDto : ExampleDto() object Type2ExampleDto : ExampleDto() data class Type3ExampleDto(val name: Int, val age: Int) : ExampleDto() data class Type4ExampleDto(val name: Int, val age: Int) : ExampleD

我有以下数据类:

sealed class ExampleDto

object Type1ExampleDto : ExampleDto()

object Type2ExampleDto : ExampleDto()

data class Type3ExampleDto(val name: Int, val age: Int) : ExampleDto()

data class Type4ExampleDto(val name: Int, val age: Int) : ExampleDto()

data class Type5ExampleDto(val email: String) : ExampleDto()

data class Type6ExampleDto(val name: Int, val age: Int, val email: String) : ExampleDto()
特别是,
Type3ExampleDto
Type4ExampleDto
Type6ExampleDto
共享一些公共字段,但区分类型对我的业务逻辑来说很重要(即,即使
Type3ExampleDto
Type4ExampleDto
是相同的,我也必须知道我是属于type3还是type4情况)

在我的一个方法中,我有以下调用:

when (type) {
            is Type3ExampleDto -> myMethod(type.vote, type.text)
            is Type4ExampleDto -> myMethod(type.vote, type.text)
            is Type6ExampleDto -> myMethod(type.vote, type.text)
            else -> null
        }
我发现很难看,我在所有3个病例中都做了相同的手术,并且重复了相同的句子

Type3ExampleDto
Type4ExampleDto
Type6ExampleDto
作为某种接口的实现是有意义的,仅仅因为只有在这一点上,我在做这种丑陋的重复

如果所有三个DTO都实现以下接口

interface MyInterface{
fun getVote() : Int
fun getText() : String

}
我可以写:

if (type is MyInterface) {
    myMethod(type.getVote(), type.getText())
}
所以,创建这个接口只是为了解决这个孤立的重复是可以接受的


谢谢

注意,您可以像这样更干净地完成:

interface NameAndAgeDto {
    val name: Int
    val age: Int
}

data class Type3ExampleDto(override val name: Int, override val age: Int) : ExampleDto(), NameAndAgeDto

if (type is NameAndAgeDto) {
    myMethod(type.name, type.age)
}


是否“可接受”取决于意见。在我看来很好。

您可以更改您的模型,使您的逻辑基于行为,而不是继承
这种建模方法是基于(但不完全是)策略设计模式的原则

如果仍然希望所有类型都属于某个父类型,则可以使用标记接口(不使用任何方法)

如果需要类作为枚举
在这种情况下,
超过
密封类
时,所有选项都不包含
null->

interface HasName {
    val name: String
}

interface HasAge {
    val age: Int
}

interface HasEmail {
    val email: String
}

object Type1

object Type2

data class Type3(
        override val name: String,
        override val age: Int
) : HasName, HasAge

data class Type4(
        override val name: String,
        override val age: Int
) : HasName, HasAge

data class Type5(
        override val email: String
) : HasEmail

data class Type6(
        override val name: String,
        override val age: Int,
        override val email: String
) : HasName, HasAge, HasEmail

// Then you can pass any object to it.
fun main(obj: Any) {
    // Koltin type-casts it nicely to both interfaces.
    if (obj is HasName && obj is HasAge) {
        myMethod(text = obj.name, vote = obj.age)
    }
}

fun myMethod(vote: Int, text: String) {

}
interface DTO

interface HasName {
    val name: String
}

interface HasAge {
    val age: Int
}

interface HasEmail {
    val email: String
}

object Type1 : DTO

object Type2 : DTO

data class Type3(
        override val name: String,
        override val age: Int
) : HasName, HasAge, DTO

data class Type4(
        override val name: String,
        override val age: Int
) : HasName, HasAge, DTO

data class Type5(
        override val email: String
) : HasEmail, DTO

data class Type6(
        override val name: String,
        override val age: Int,
        override val email: String
) : HasName, HasAge, HasEmail, DTO

// Here, it is DTO instead of Any
fun main(obj: DTO) {
    if (obj is HasName && obj is HasAge) {
        myMethod(text = obj.name, vote = obj.age)
    }
}