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

这些库充满了带有setter、getter和Builder类的pojo。现在我已经在谷歌上找到了在Kotlin中实现Builders的最佳方法,但没有成功。

第二次更新:问题是如何写一个建设者设计模式的一个简单的pojo与一些参数在Kotlin?下面的代码是我尝试编写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中的模式和实现基本保持不变。由于默认值,您有时可以跳过它,但对于更复杂的对象创建,构建器仍然是一个不可省略的有用工具。

其他回答

我刚刚发现了一个有趣的方法来创建kotlin构建器:

如您所见,moduleBuilder可以用于其他grafana构建。

代码如下:

class Grafana(
    private val module: String,
    private val scene: String,
    private val action: String,
    private val metric: String
) {
    companion object {
        fun build(module: String, scene: String, action: String, metric: String) =
            Grafana(module, scene, action, metric)

        val builder = ::build.curriedBuilder()

        private fun <P1, P2, P3, P4, R> Function4<P1, P2, P3, P4, R>.curriedBuilder() =
            fun(p1: P1) = fun(p2: P2) = fun(p3: P3) = fun(p4: P4) = this(p1, p2, p3, p4)
    }

    fun report() = Unit
}


val moduleBuilder = Grafana.builder("module")
val scene = moduleBuilder("scene")
val gfA = scene("action")("metric")
gfA.report()

val sceneB = moduleBuilder("sceneB")
val gfB = sceneB("action")("metric")
gfB.report()

val gfC = Grafana.builder("xx")("xxx")("xxxx")("xxxx")
gfC.report()

因为我使用Jackson库从JSON解析对象,我需要一个空构造函数,我不能有可选字段。而且所有字段都必须是可变的。然后我可以使用这个漂亮的语法,它做的事情与生成器模式相同:

val car = Car().apply{ model = "Ford"; year = 2000 }
class Foo private constructor(@DrawableRes requiredImageRes: Int, optionalTitle: String?) {

    @DrawableRes
    @get:DrawableRes
    val requiredImageRes: Int

    val optionalTitle: String?

    init {
        this.requiredImageRes = requiredImageRes
        this.requiredImageRes = optionalTitle
    }

    class Builder {

        @DrawableRes
        private var requiredImageRes: Int = -1

        private var optionalTitle: String? = null

        fun requiredImageRes(@DrawableRes imageRes: Int): Builder {
            this.intent = intent
            return this
        } 

        fun optionalTitle(title: String): Builder {
            this.optionalTitle = title
            return this
        }

        fun build(): Foo {
            if(requiredImageRes == -1) {
                throw IllegalStateException("No image res provided")
            }
            return Foo(this.requiredImageRes, this.optionalTitle)
        }

    }

}

我在一个Kotlin项目中工作,该项目公开了一个由Java客户机使用的API (Java客户机不能利用Kotlin语言结构)。我们必须添加构建器以使它们在Java中可用,因此我创建了@Builder注释:https://github.com/ThinkingLogic/kotlin-builder-annotation 它基本上是Kotlin的Lombok @Builder注释的替代品。

我在Kotlin中实现了一个基本的Builder模式,代码如下:

data class DialogMessage(
        var title: String = "",
        var message: String = ""
) {


    class Builder( context: Context){


        private var context: Context = context
        private var title: String = ""
        private var message: String = ""

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

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

        fun build() = KeyoDialogMessage(
                title,
                message
        )

    }

    private lateinit var  dialog : Dialog

    fun show(){
        this.dialog= Dialog(context)
        .
        .
        .
        dialog.show()

    }

    fun hide(){
        if( this.dialog != null){
            this.dialog.dismiss()
        }
    }
}

最后

Java:

new DialogMessage.Builder( context )
       .title("Title")
       .message("Message")
       .build()
       .show();

科特林:

DialogMessage.Builder( context )
       .title("Title")
       .message("")
       .build()
       .show()