在Kotlin的建造者模式

IHC*_*oid 8 kotlin

我是kotlin世界的新手.我有一个用Java编写的现有构建器,并希望将其转换为Kotlin,因为我将项目迁移到Android中的kotlin.但是,Android Studio内置工具似乎有一些错误,然后转换后的代码不可编译.它显示我UserBuilder班级中的变量无法访问.

这是教程中的Java代码

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

    }
}
Run Code Online (Sandbox Code Playgroud)

自动转换的kotlin代码:

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

    }
}
Run Code Online (Sandbox Code Playgroud)

更新

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

    }
}
Run Code Online (Sandbox Code Playgroud)

kco*_*ock 5

鉴于它是Kotlin,你实际上可以使用数据类使这更简单.

data class User(val firstName: String, 
        val lastName: String,
        val age: Int = 0,
        val phone: String? = null,
        val address: String? = null)
Run Code Online (Sandbox Code Playgroud)

就是这样!前两个参数是必需的,但如果要指定更多,则只需按名称指定它们:

val user = User("John", "Doe", phone = "555-1212")
Run Code Online (Sandbox Code Playgroud)

不需要建设者!

  • 嗨,谢谢你的帮助.我知道kotlin有可选的params支持,但我仍然希望有构建器,因为我的kotlin库将用于Java. (2认同)
  • 这并不能真正取代构建器模式。 (2认同)

cha*_*l03 0

只需像以前一样进行简单的转换即可。

现在您将看到UserBuilderwill 有internal访问修饰符,只需删除它并添加 public 或任何您的要求。


编辑1

好吧,internal您的代码中没有关键字Kotlin,我在检查您的代码时忽略了这一点。

所以现在你需要做的是在Person类中创建一个对象并将你的UserBuilder类放入其中。

检查以下代码:

class Person private constructor(builder: 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
}
object Builder {
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)
    }

}
}
}
Run Code Online (Sandbox Code Playgroud)

这应该像在您的 Java 代码中一样工作。

希望能帮助到你。