嗨,我是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
        }
    }
}

当前回答

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

    }

}

其他回答

对于简单类,不需要单独的构建器。您可以像Kirill Rakhman描述的那样使用可选的构造函数参数。

如果你有更复杂的类,那么Kotlin提供了一种方法来创建Groovy风格的Builders/DSL:

类型安全的建筑商

这里有一个例子:

Github示例-构建器/汇编器

class Person(
    val name:String,
    val family:String,
    val age:Int,
    val nationalCode: String?,
    val email: String?,
    val phoneNumber: String?
) {

    // Private constructor
    private constructor(builder: Builder) : this (
        builder.name,
        builder.family,
        builder.age,
        builder.nationalCode,
        builder.email,
        builder.phoneNumber
    )

    // Builder class

    // 1 Necessary parameters in Builder class : name , family
    class Builder(val name :String,val family :String) {

        // 2 Optional parameters in Builder class :
        var age: Int = 0
            private set
        var nationalCode: String? = null
            private set
        var email: String? = null
            private set
        var phoneNumber: String? = null
            private set

        fun age(age: Int) = apply { this.age = age }
        fun nationalCode(nationalCode: String) =
            apply { this.nationalCode = nationalCode }
        fun email(email: String) = apply { this.email = email }
        fun phoneNumber(phoneNumber: String) =
            apply { this.phoneNumber = phoneNumber }

        // 3 Create
        fun create() = Person(this)

    }
}

存取资料:

val firstPerson = Person.Builder(
    name = "Adnan",
    family = "Abdollah Zaki")
    .age(32)
    .email("Adnan9011@gmail.com")
    .phoneNumber("+989333030XXX")
    .nationalCode("04400XXXXX")
    .create()

val secondPerson = Person.Builder(
    name = "Foroogh",
    family = "Varmazyar")
    .create()

在kotlin中可以使用可选参数 例子:

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

然后

myFunc("a")
myFunc("a", 1)
myFunc("a", 1, 2)
myFunc("a", 1, 2, "b")

上面的答案有一点改变和改进

class MyDialog {
  private var title: String? = null
  private var content: String? = null
  private var confirmButtonTitle: String? = null
  private var rejectButtonTitle: String? = null

  @DrawableRes
  private var icon: Int? = null


  fun show() {
    // set dialog content here and show at the end
  }

  class Builder {
      private var dialog: MyDialog = MyDialog()

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

      fun icon(@DrawableRes icon: Int) = apply { dialog.icon = icon }

      fun content(content: String) = apply { dialog.content = content }

      fun confirmTitle(confirmTitle: String) = apply { dialog.confirmButtonTitle = confirmTitle }

      fun rejectButtonTitle(rejectButtonTitle: String) = apply { dialog.rejectButtonTitle = rejectButtonTitle }

      fun build() = dialog
  }
}

和使用

MyDialog.Builder()
        .title("My Title")
        .content("My content here")
        .icon(R.drawable.bg_edittext)
        .confirmTitle("Accept")
        .rejectButtonTitle("Cancel")
        .build()
        .show()

我想说的是,Kotlin中的模式和实现基本保持不变。由于默认值,您有时可以跳过它,但对于更复杂的对象创建,构建器仍然是一个不可省略的有用工具。