如何使用构建器模式构建嵌套列表?
How can I build a nested list using builder pattern?
我正在尝试使用构建器模式为 GraphQL 语法创建一个查询构建器。我已经为过滤部分做了:
我想以编程方式找到一种方法来说明我想从查询中取回哪些数据。 (注意:在查询的 title
部分被硬编码到 QueryBuilder 之前。
为此,我制作了一个名为 Entity 的 class,它有一个自身列表作为属性。
class Entity(
private val entity: EntityType,
private val entities: MutableList<Entity> = mutableListOf()
) {
override fun toString(): String {
return if (this.entities.isEmpty()) {
entity.str
} else {
this.entity.str + "{" + this.entities.onEach {
it.toString()
}.joinToString(" ") + "}"
}
}
}
我让它开始工作了。但是要构建结构。然后我必须附加到列表并“访问”实体列表以访问该列表中的实体。
例如,如果我要构建此查询:
{
events(place:"Somewhere", area:"The place"){
title
location{
coordinates{
longitude
latitude
}
}
}
}
然后我需要在实体层中向下移动 2 个级别,按照我现在的方式,我的代码变得非常宽。
fun main() {
val e1 = listOf<Entity>(
Entity(EntityType.TITLE),
Entity(EntityType.LOCATION,
mutableListOf(
Entity(EntityType.COORDINATES,
mutableListOf(
Entity(EntityType.LONGITUDE),
Entity(EntityType.LATITUDE)
)
)
)
)
)
val q1 = Query.Builder()
.filter(FilterType.PLACE, "Somewhere")
.filter(FilterType.AREA,"The place")
.add(e1)
.build()
println(q1.query)
}
所以我在考虑使用构建器模式。或者其他更聪明的东西。
提前感谢您的帮助,祝您有愉快的一天。
顺便说一句:我正在使用以下枚举:
enum class EntityType(val str: String) {
EVENTS("events"),
TITLE("title"),
LOCATION("location"),
COORDINATES("coordinates"),
LONGITUDE("longitude"),
LATITUDE("latitude"),
}
enum class Filter(val str: String) {
PLACE("place"),
AREA("area"),
}
我的其余代码如下所示:
class Filter {
var filters = mutableMapOf<FilterType, Any>()
override fun toString(): String {
return if (filters.isNotEmpty()) {
"(" + filters.map {
if (it.value is Int || it.value is Long) {
it.key.str + ":" + it.value + ","
} else {
it.key.str + ":\"" + it.value + "\","
}
}.joinToString(" ").dropLast(1) + ")"
} else {
""
}
}
}
class Query private constructor(val query: String) {
class Builder {
private lateinit var entities: List<Entity>
private var filter = Filter()
fun filter(key: FilterType, value: Any) = apply {
this.filter.filters[key] = value
}
fun add(entities: List<Entity>) = apply {
this.entities = entities
}
private fun collect(root:String):String {
return "{$root$filter{${entities.joinToString(" ")}}}"
}
fun build(): Query {
return Query(collect("events"))
}
}
看看Kotlin Type-Safe Builders documentation。您可以找到有关如何为 HTML
执行此操作的示例
我正在尝试使用构建器模式为 GraphQL 语法创建一个查询构建器。我已经为过滤部分做了:
我想以编程方式找到一种方法来说明我想从查询中取回哪些数据。 (注意:在查询的 title
部分被硬编码到 QueryBuilder 之前。
为此,我制作了一个名为 Entity 的 class,它有一个自身列表作为属性。
class Entity(
private val entity: EntityType,
private val entities: MutableList<Entity> = mutableListOf()
) {
override fun toString(): String {
return if (this.entities.isEmpty()) {
entity.str
} else {
this.entity.str + "{" + this.entities.onEach {
it.toString()
}.joinToString(" ") + "}"
}
}
}
我让它开始工作了。但是要构建结构。然后我必须附加到列表并“访问”实体列表以访问该列表中的实体。
例如,如果我要构建此查询:
{
events(place:"Somewhere", area:"The place"){
title
location{
coordinates{
longitude
latitude
}
}
}
}
然后我需要在实体层中向下移动 2 个级别,按照我现在的方式,我的代码变得非常宽。
fun main() {
val e1 = listOf<Entity>(
Entity(EntityType.TITLE),
Entity(EntityType.LOCATION,
mutableListOf(
Entity(EntityType.COORDINATES,
mutableListOf(
Entity(EntityType.LONGITUDE),
Entity(EntityType.LATITUDE)
)
)
)
)
)
val q1 = Query.Builder()
.filter(FilterType.PLACE, "Somewhere")
.filter(FilterType.AREA,"The place")
.add(e1)
.build()
println(q1.query)
}
所以我在考虑使用构建器模式。或者其他更聪明的东西。
提前感谢您的帮助,祝您有愉快的一天。
顺便说一句:我正在使用以下枚举:
enum class EntityType(val str: String) {
EVENTS("events"),
TITLE("title"),
LOCATION("location"),
COORDINATES("coordinates"),
LONGITUDE("longitude"),
LATITUDE("latitude"),
}
enum class Filter(val str: String) {
PLACE("place"),
AREA("area"),
}
我的其余代码如下所示:
class Filter {
var filters = mutableMapOf<FilterType, Any>()
override fun toString(): String {
return if (filters.isNotEmpty()) {
"(" + filters.map {
if (it.value is Int || it.value is Long) {
it.key.str + ":" + it.value + ","
} else {
it.key.str + ":\"" + it.value + "\","
}
}.joinToString(" ").dropLast(1) + ")"
} else {
""
}
}
}
class Query private constructor(val query: String) {
class Builder {
private lateinit var entities: List<Entity>
private var filter = Filter()
fun filter(key: FilterType, value: Any) = apply {
this.filter.filters[key] = value
}
fun add(entities: List<Entity>) = apply {
this.entities = entities
}
private fun collect(root:String):String {
return "{$root$filter{${entities.joinToString(" ")}}}"
}
fun build(): Query {
return Query(collect("events"))
}
}
看看Kotlin Type-Safe Builders documentation。您可以找到有关如何为 HTML
执行此操作的示例