design-patterns - 如何在 Kotlin 中实现 Builder 模式?

您好,我是 Kotlin 世界的新手。我喜欢我目前所看到的,并开始考虑将我们在应用程序中使用的一些库从 Java 转换为 Kotlin。

这些库充满了带有 setter、getter 和 Builder 类的 Pojo。现在我用谷歌搜索找到在 Kotlin 中实现构建器的最佳方法,但没有成功。

第二次更新:问题是如何在 Kotlin 中为带有一些参数的简单 pojo 编写 Builder 设计模式?下面的代码是我尝试编写java代码,然后使用eclipse-kotlin-plugin转换成Kotlin。

class Car private constructor(builder:Car.Builder) {
    var model:String? = null
    var year:Int = 0
    init {
        this.model = builder.model
        this.year = builder.year
    }
    companion object Builder {
        var model:String? = null
        private set

        var year:Int = 0
        private set

        fun model(model:String):Builder {
            this.model = model
            return this
        }
        fun year(year:Int):Builder {
            this.year = year
            return this
        }
        fun build():Car {
            val car = Car(this)
            return car
        }
    }
}

最佳答案

首先,在大多数情况下,您不需要在 Kotlin 中使用构建器,因为我们有默认参数和命名参数。这使您可以编写

class Car(val model: String? = null, val year: Int = 0)

并像这样使用它:

val car = Car(model = "X")

如果您绝对想使用构建器,可以这样做:

使 Builder 成为 companion object 没有意义,因为 object 是单例。而是将其声明为嵌套类(在 Kotlin 中默认为静态)。

将属性移动到构造函数,以便对象也可以以常规方式实例化(如果不应该将构造函数设为私有(private))并使用辅助构造函数,该构造函数接受构建器并委托(delegate)给主构造函数。代码如下所示:

class Car( //add private constructor if necessary
        val model: String?,
        val year: Int
) {

    private constructor(builder: Builder) : this(builder.model, builder.year)

    class Builder {
        var model: String? = null
            private set

        var year: Int = 0
            private set

        fun model(model: String) = apply { this.model = model }

        fun year(year: Int) = apply { this.year = year }

        fun build() = Car(this)
    }
}

用法:val car = Car.Builder().model("X").build()

可以使用 builder DSL 进一步缩短此代码。 :

class Car (
        val model: String?,
        val year: Int
) {

    private constructor(builder: Builder) : this(builder.model, builder.year)

    companion object {
        inline fun build(block: Builder.() -> Unit) = Builder().apply(block).build()
    }

    class Builder {
        var model: String? = null
        var year: Int = 0

        fun build() = Car(this)
    }
}

用法:val car = Car.build { model = "X"}

如果某些值是必需的并且没有默认值,则需要将它们放入构建器的构造函数中以及我们刚刚定义的 build 方法中:

class Car (
        val model: String?,
        val year: Int,
        val required: String
) {

    private constructor(builder: Builder) : this(builder.model, builder.year, builder.required)

    companion object {
        inline fun build(required: String, block: Builder.() -> Unit) = Builder(required).apply(block).build()
    }

    class Builder(
            val required: String
    ) {
        var model: String? = null
        var year: Int = 0

        fun build() = Car(this)
    }
}

用法:val car = Car.build(required = "requiredValue") { model = "X"}

https://stackoverflow.com/questions/36140791/

相关文章:

android-studio - Android Studio 3.0 - 找不到方法 'com.a

kotlin - Kotlin 中等效的 Swift 'if let' 语句

android-studio - Unresolved reference : kotlinx

java - Java 的 String[] 的 Kotlin 等价物是什么?

asynchronous - Kotlin协程中的launch/join和async/await有什

hibernate - 带有 JPA : default constructor hell 的 Ko

kotlin - 什么是 Kotlin 双键 (!!) 运算符?

random - 如何在 Kotlin 中获取随机数?

kotlin - bool 值的使用?在 if 表达式中

kotlin - Kotlin 中的单个感叹号