如何在 Kotlin 中实现 Builder 模式? [英] How to implement Builder pattern in Kotlin?

查看:76
本文介绍了如何在 Kotlin 中实现 Builder 模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Hi I am a newbie in the Kotlin world. I like what I see so far and started to think to convert some of our libraries we use in our application from Java to Kotlin.

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

These libraries are full of Pojos with setters, getters and Builder classes. Now I have googled to find what is the best way to implement Builders in Kotlin but no success.

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

2nd Update: The question is how to write a Builder design-pattern for a simple pojo with some parameters in Kotlin? The code below is my attempt by writing java code and then using the eclipse-kotlin-plugin to convert to 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 中使用构建器,因为我们有默认和命名参数.这使您能够编写

First and foremost, in most cases you don't need to use builders in Kotlin because we have default and named arguments. This enables you to write

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

并像这样使用它:

val car = Car(model = "X")

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

If you absolutely want to use builders, here's how you could do it:

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

Making the Builder a companion object doesn't make sense because objects are singletons. Instead declare it as an nested class (which is static by default in Kotlin).

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

Move the properties to the constructor so the object can also be instantiated the regular way (make the constructor private if it shouldn't) and use a secondary constructor that takes a builder and delegates to the primary constructor. The code will look as follow:

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 进一步缩短此代码:

This code can be shortened additionally by using a 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方法中:

If some values are required and don't have default values, you need to put them in the constructor of the builder and also in the build method we just defined:

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" }

这篇关于如何在 Kotlin 中实现 Builder 模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆