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

当前回答

在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")

其他回答

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

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

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

我迟到了。如果我必须在项目中使用Builder模式,我也遇到了同样的困境。后来,经过研究,我意识到这是完全不必要的,因为Kotlin已经提供了命名参数和默认参数。

如果你真的需要实施,Kirill Rakhman的答案是关于如何以最有效的方式实施的可靠答案。您可能会发现另一件有用的事情是https://www.baeldung.com/kotlin-builder-pattern,您可以将其与Java和Kotlin的实现进行比较和对比

我个人从来没有在Kotlin见过一个建筑工人,但也许只有我这样。

所有需要的验证都发生在init块中:

class Car(val model: String,
          val year: Int = 2000) {

    init {
        if(year < 1900) throw Exception("...")
    }
}

在这里,我冒昧地猜测,您并不真的希望型号和年份可以更改。而且,这些默认值似乎没有任何意义,(特别是null作为name),但为了演示目的,我留下了一个。

一个意见: 在Java中使用的构建器模式意味着不需要命名参数。在带有命名参数的语言(如Kotlin或Python)中,使用带有长串(可能是可选的)参数的构造函数是一个很好的实践。

一种方法是做以下事情:

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

使用示例:

val car = Car.Builder()
  .model("Ford Focus")
  .color("Black")
  .type("Type")
  .build()