如何使用构建器模式构建嵌套列表? [英] How can I build a nested list using builder pattern?

查看:78
本文介绍了如何使用构建器模式构建嵌套列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过使用构建器模式为GraphQL语法创建查询构建器.我已经在过滤部分做到了:

I am trying to make a query builder for GraphQL syntax, by using a builder pattern. I already did it for the filtering part:

我想以编程方式找到一种方法,说出我想从查询中获取哪些数据. (注意:在查询的title部分被硬编码到QueryBuilder中之前.

I want to programatically make a way to say what data I want to get back from the query. (NOTE: before the title part of the query was hardcoded into the QueryBuilder.

为此,我制作了一个名为Entity的类,该类具有一个自身列表作为属性.

So for that I made a class called Entity which has a list of itself as an attribute.

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(" ") + "}"
        }
    }
}

我明白了.但是要建立结构.那么我必须将其添加到列表中并访问"实体列表以访问该列表中的实体.

And I got it to work. But to build the structure. then I have to append to the list and "visit" the list of the entity to visit the entities in that list.

例如,如果我要构建此查询:

For example if I want to build this query:

{
  events(place:"Somewhere", area:"The place"){
    title
    location{
      coordinates{
        longitude
        latitude
      }
    }
  }
}

然后,我需要在实体的各个层次上向下两层,然后按现在的方式进行操作,然后我的代码将变得越来越宽.

Then I need to go 2 levels down in the layers of the Entity, And the way I am doing it now, then my code is getting very wide.

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

所以我在考虑使用构建器模式.或其他会更聪明的东西.

So I was thinking to use builder pattern. Or something else which will be smarter.

提前感谢您的帮助,祝您有愉快的一天.

Thank you in advance for your help, and have a nice day.

顺便说一句:我正在使用以下枚举:

BTW: I am using following enums:

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

推荐答案

看看

Take a look to Kotlin Type-Safe Builders documentation. You can find an example on how to do it for HTML

这篇关于如何使用构建器模式构建嵌套列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆