How to implement Builder pattern in Kotlin?

后端 未结 13 1561
半阙折子戏
半阙折子戏 2020-11-29 16:18

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.

T

相关标签:
13条回答
  • 2020-11-29 17:04

    you can use optional parameter in kotlin example:

    fun myFunc(p1: String, p2: Int = -1, p3: Long = -1, p4: String = "default") {
        System.out.printf("parameter %s %d %d %s\n", p1, p2, p3, p4)
    }
    

    then

    myFunc("a")
    myFunc("a", 1)
    myFunc("a", 1, 2)
    myFunc("a", 1, 2, "b")
    
    0 讨论(0)
  • 2020-11-29 17:05

    I implemented a basic Builder pattern in Kotlin with the follow code:

    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()
            }
        }
    }
    

    And finally

    Java:

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

    Kotlin:

    DialogMessage.Builder( context )
           .title("Title")
           .message("")
           .build()
           .show()
    
    0 讨论(0)
  • 2020-11-29 17:08

    One approach is to do something like the following:

    class Car(
      val model: String?,
      val color: String?,
      val type: String?) {
    
        data class Builder(
          var model: String? = null,
          var color: String? = null,
          var type: String? = null) {
    
            fun model(model: String) = apply { this.model = model }
            fun color(color: String) = apply { this.color = color }
            fun type(type: String) = apply { this.type = type }
            fun build() = Car(model, color, type)
        }
    }
    

    Usage sample:

    val car = Car.Builder()
      .model("Ford Focus")
      .color("Black")
      .type("Type")
      .build()
    
    0 讨论(0)
  • 2020-11-29 17:11

    I am late to the party. I also encountered the same dilemma if I had to use Builder pattern in the project. Later, after research I have realized it is absolutely unnecessary since Kotlin already provides the named arguments and default arguments.

    If you really need to implement, Kirill Rakhman's answer is solid answer on how to implement in most effective way. Another thing you may find it useful is https://www.baeldung.com/kotlin-builder-pattern you can compare and contrast with Java and Kotlin on their implementation

    0 讨论(0)
  • 2020-11-29 17:19

    For a simple class you don't need a separate builder. You can make use of optional constructor arguments as Kirill Rakhman described.

    If you have more complex class then Kotlin provides a way to create Groovy style Builders/DSL:

    Type-Safe Builders

    Here is an example:

    Github Example - Builder / Assembler

    0 讨论(0)
  • 2020-11-29 17:20

    I personally have never seen a builder in Kotlin, but maybe it is just me.

    All validation one needs happens in the init block:

    class Car(val model: String,
              val year: Int = 2000) {
    
        init {
            if(year < 1900) throw Exception("...")
        }
    }
    

    Here I took a liberty to guess that you don't really wanted model and year to be changeable. Also those default values seems to have no sense, (especially null for name) but I left one for demonstration purposes.

    An Opinion: The builder pattern used in Java as a mean to live without named parameters. In languages with named parameters (like Kotlin or Python) it is a good practice to have constructors with long lists of (maybe optional) parameters.

    0 讨论(0)
提交回复
热议问题