编写正确的 DSL



我希望能够编写调用工厂方法来创建对象的实例,而不是直接调用构造函数。

我有一个名为 PersonFactory 的工厂,它实现了一个名为 getPresonTypeOne(name: String, age:Int, address: String) 的方法。 PersonTypeOne有三个成员变量,分别nameageaddress。我希望能够编写一些调用getPresonTypeOne来创建PersonTypeOne实例的东西,而不是直接调用PersonTypeOne构造函数。

理想情况下,看起来像这样的东西

class PersonTypeOne(
      val name: String, 
      val age: Int, 
      val address: String) {
    ...
}

personTypeOne {
    withName {
       ...
    }
    withAge {
       ...
    }
    withAddress {
       ...
    } 
}

我希望DSL有效地产生如下所示的调用:personFactory.getPresonTypeOne(name, age, address)

我已经环顾四周了很多,但我只找到了我能够通过直接调用 PersonTypeOne 构造函数来做到这一点的示例。

我不确定,你的缩进是什么。如果只想隐藏出厂调用,则不需要 DSL。带有命名参数的函数将完成这项工作:

fun personTypeOne(name: String, age: Int, address: String): PersonTypeOne =
    PersonFactory.getPersonTypeOne(name, age, address)
val person1 = personTypeOne(name = "Name", address = "address", age = 42)

如果你确实需要一个DSL,你需要定义一个构建器帮助程序类,其中包含每个属性的方法和一个用于使用此构建器的函数:

class PersonTypOneBuilder {
    private var name: String? = null
    private var age: Int? = null
    private var address: String? = null
    fun withName(name: () -> String) {
        this.name = name()
    }
    fun withAge(age: () -> Int) {
        this.age = age()
    }
    fun withAddress(address: () -> String) {
        this.address = address()
    }
    fun build() =
        PersonFactory.getPersonTypeOne(
            name ?: throw IllegalStateException(),
            age ?: throw IllegalStateException(),
            address ?: throw IllegalStateException()
        )
}
fun personTypeOne(block: PersonTypOneBuilder.() -> Unit): PersonTypeOne =
    PersonTypOneBuilder().apply(block).build()

现在您可以使用 DSL:

val person2 = personTypeOne {
    withName {
        "Bla"
    }
    withAddress {
        "address"
    }
    withAge {
        42
    }
}

相关内容

  • 没有找到相关文章

最新更新