Как избежать необходимости разделять группы точкой с запятой
Используя идиоматический формат, используя отдельные строки.В конце концов, весь смысл DSL состоит в том, чтобы сделать код очень читабельным, показывая иерархическую структуру, и делая все в одной строке, отрицательно сказывается на цели:
val grp = group {
member {
name ("Bob")
}
member {
name ("Sandy")
}
}
Могу ли я добраться доиспользовать лямбду для задания имени вместо вызова функции?
Было бы логичнее и идиоматичнее удалить функцию имени и просто присвоить значение свойству:
name = "Bob"
Но да, вы также можете заменить свою функцию имени на
fun name(block: () -> String) {
this.name = block()
}
и использовать
name {
"Sandy"
}
Можно ли избежать того, чтобы имя было изменяемым в классе MEMBER?
Да: лямбда, передаваемая в функцию member (), настроит дополнительный класс MemberBuilder, который будет изменяемым, но позволит создать неизменный MEMBER:
fun group(create: GROUP.() -> Unit) = GROUP().apply(create)
class GROUP {
private val members = mutableSetOf<MEMBER>()
fun member(configure: MemberBuilder.() -> Unit) {
val memberBuilder = MemberBuilder()
memberBuilder.configure()
members.add(memberBuilder.build())
}
override fun toString() = members.toString()
}
class MEMBER(val name: String) {
override fun toString() = "MEMBER($name)"
}
class MemberBuilder {
var name = "";
fun build() = MEMBER(name)
}
fun main(args: Array<String>) {
val grp = group {
member {
name = "Bob"
}
member {
name = "Sandy"
}
}
println(grp)
}
Также,обратите внимание, что классы, по соглашению, являются PascalCased, а не ALL_CAPS.