I am new to kotlin world. I have a existing builder written in Java and would like to convert it to Kotlin as I am migration the project to kotlin in Android. However, the Android Studio built-in tool seems have some bugs, then converted code is not compilable. It is showing inaccessible to the variables in my UserBuilder
class.
Here is the Java code from tutorial
public class Person {
private final String firstName; // required
private final String lastName; // required
private final int age; // optional
private final String phone; // optional
private final String address; // optional
private Person(UserBuilder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
this.address = builder.address;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getPhone() {
return phone;
}
public String getAddress() {
return address;
}
public static class UserBuilder {
private final String firstName;
private final String lastName;
private int age;
private String phone;
private String address;
public UserBuilder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public UserBuilder address(String address) {
this.address = address;
return this;
}
public Person build() {
return new Person(this);
}
}
}
The auto converted kotlin code:
class Person private constructor(builder: UserBuilder) {
val firstName: String // required
val lastName: String // required
val age: Int // optional
val phone: String // optional
val address: String // optional
init {
//cannot access the variables, they are private in UserBuilder
this.firstName = builder.firstName
this.lastName = builder.lastName
this.age = builder.age
this.phone = builder.phone
this.address = builder.address
}
class UserBuilder(private val firstName: String, private val lastName: String) {
private var age: Int = 0
private var phone: String? = null
private var address: String? = null
fun age(age: Int): UserBuilder {
this.age = age
return this
}
fun phone(phone: String): UserBuilder {
this.phone = phone
return this
}
fun address(address: String): UserBuilder {
this.address = address
return this
}
fun build(): Person {
return Person(this)
}
}
}
UPDATED
class Person private constructor(builder: UserBuilder) {
val firstName: String // required
val lastName: String // required
val age: Int // optional
val phone: String? // optional
val address: String? // optional
init {
this.firstName = builder.firstName
this.lastName = builder.lastName
this.age = builder.age
this.phone = builder.phone
this.address = builder.address
}
class UserBuilder(internal val firstName: String, internal val lastName: String) {
internal var age: Int = 0
internal var phone: String? = null
internal var address: String? = null
fun age(age: Int): UserBuilder {
this.age = age
return this
}
fun phone(phone: String): UserBuilder {
this.phone = phone
return this
}
fun address(address: String): UserBuilder {
this.address = address
return this
}
fun build(): Person {
return Person(this)
}
}
}
A builder pattern provides an API to construct an object step- by-step. Builder patterns are particularly useful when objects need to be created dynamically.
For most use cases you don't need a Builder pattern in Kotlin and are fine just using a constructor with named arguments and default parameters. In case you have a complex object and/or have a stateful configuration that you want to pass around until you have build the complete object, a Builder is useful.
Introduction to Kotlin Builder Pattern. Kotlin builder pattern is used to handle object building which contains lots of parameters, and at the time of making the mutable object, then we are constructing it, which was often used but rarely creating our own.
Builder pattern aims to “Separate the construction of a complex object from its representation so that the same construction process can create different representations.” It is used to construct a complex object step by step and the final step will return the object.
Given it's Kotlin, you can actually make this far simpler using a data class.
data class User(val firstName: String,
val lastName: String,
val age: Int = 0,
val phone: String? = null,
val address: String? = null)
And that's it! The first two parameters are required, but if you want to specify more, you just specify them by name:
val user = User("John", "Doe", phone = "555-1212")
No builder needed!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With