编写适当的 DSL
Writing proper DSL
我希望能够编写调用工厂方法来创建对象的实例,而不是直接调用构造函数。
我有一个名为 PersonFactory
的工厂,它实现了一个名为 getPresonTypeOne(name: String, age:Int, address: String)
的方法。 PersonTypeOne
有3个成员变量,分别是name
、age
、address
。我希望能够编写一些调用 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,其中包含每个属性的方法和一个使用此构建器的函数:
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
}
}
我希望能够编写调用工厂方法来创建对象的实例,而不是直接调用构造函数。
我有一个名为 PersonFactory
的工厂,它实现了一个名为 getPresonTypeOne(name: String, age:Int, address: String)
的方法。 PersonTypeOne
有3个成员变量,分别是name
、age
、address
。我希望能够编写一些调用 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,其中包含每个属性的方法和一个使用此构建器的函数:
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
}
}