मैं बिल्डर पैटर्न का उपयोग करके नेस्टेड सूची कैसे बना सकता हूं?

Nov 30 2020

मैं एक बिल्डर पैटर्न का उपयोग करके GraphQL सिंटैक्स के लिए क्वेरी बिल्डर बनाने की कोशिश कर रहा हूं। मैंने इसे पहले ही फ़िल्टरिंग भाग के लिए कर लिया था:

मैं प्रोग्राम को यह कहने का तरीका बनाना चाहता हूं कि मुझे किस डेटा को क्वेरी से वापस लेना है। (नोट: titleक्वेरी के भाग को क्वेरीबर्ल्ट में हार्डकोड किया गया था।

तो इसके लिए मैंने Entity नाम की एक क्लास बनाई, जिसमें एक विशेषता के रूप में खुद की एक सूची है।

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

इसलिए मैं बिल्डर पैटर्न का उपयोग करने के लिए सोच रहा था। या कुछ और जो होशियार होगा।

आपकी मदद के लिए अग्रिम धन्यवाद, और आपका दिन शुभ हो।

BTW: मैं निम्नलिखित 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"))
        }
    }

जवाब

1 Pelocho Dec 01 2020 at 10:48

कोटलिन टाइप-सेफ बिल्डर्स प्रलेखन पर एक नज़र डालें । आप HTML के लिए इसे कैसे करें, इस पर एक उदाहरण पा सकते हैं