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
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")
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()
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()
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
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
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.