Как описать структуры событий и получить информацию? - PullRequest
0 голосов
/ 23 февраля 2020

Я хочу написать DSL в kotlin, который описывает события в хранилище событий для генерации Java кода, JSON примеров, схемы и документации на основе этих описаний. Мой текущий подход:

Класс данных MyEvent, который содержит структуру события

data class MyEvent(val name: String, val version: Int, val content: Map<String, String>)

, так что я могу описать события как

val OrderCreated = MyEvent("OrderCreated", 1, mapOf("orderId" to "UUID", "nameOfProduct" to "String(1, 256)", "quantity" to "Integer"))
val OrderCancelled = MyEvent("OrderCancelled", 2, mapOf("orderId" to "UUID", "reason" to "String(100, 1000)"))
val OrderQuestioned = MyEvent("OrderQuestioned", 3, mapOf("orderId" to "UUID", "question" to "String(10, 1000)"))

Принимая во внимание, что «String (1, 256)» означает, что он имеет тип String с минимумом 1 и максимумом 256 символов.

Чтобы перебрать все события для генерации всего, что я хочу, мне нужно добавить вручную каждое событие в список / набор

fun scanForAllMyEventsInstances(): Set<MyEvent> {
    return hashSetOf(OrderCreated, OrderCancelled, OrderQuestioned)
}

Этот способ не кажется наилучшим.

  1. Мне не нравится, когда меня заставляют добавлять новые события в scanForAllMyEventsInstances. Я хочу описать новое событие только в одном месте.
  2. Мне не нравится создавать экземпляр MyEvent для каждого события. Это все "stati c" информация.

Итак, мой вопрос: Как бы вы это сделали? Я хотел бы получить несколько предложений.

Я использую SpringBoot на данный момент. Так что не стесняйтесь предлагать рамки.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2020

С подходом классов enum я добавил интерфейс, чтобы я мог организовать множество (разных) событий

interface MyEvent2 {
    val eventName: String
    val version: Int
    val content: Map<String, String>
}

enum class MyOrderEvents : MyEvent2 {

    OrderCreated {
        override val eventName = "OrderCreated"
        override val version = 1
        override val content = mapOf("orderId" to "UUID", "nameOfProduct" to "String(1, 256)", "quantity" to "Integer")
    },

    OrderCancelled {
        override val eventName = "OrderCancelled"
        override val version = 2
        override val content = mapOf("orderId" to "UUID", "reason" to "String(100, 1000)")
    },

    OrderQuestioned {
        override val eventName = "OrderQuestioned"
        override val version = 3
        override val content = mapOf("orderId" to "UUID", "question" to "String(10, 1000)")
    }

}

enum class MyUserEvents : MyEvent2 {

    UserCreated {
        override val eventName = "UserCreated"
        override val version = 1
        override val content = mapOf("userId" to "UUID", "name" to "String(1, 256)")
    },

    UserDeleted {
        override val eventName = "UserDeleted"
        override val version = 2
        override val content = mapOf("userId" to "UUID")
    },

    UserChanged {
        override val eventName = "UserChanged"
        override val version = 3
        override val content = mapOf("userId" to "UUID", "newName" to "String(1, 256)")
    }

}

Мне все еще нужно добавить каждый класс enum в список / набор.

fun scanForAllMyEventsInstances(): Set<MyEvent2> {
    val allEvents = HashSet<MyEvent2>()
    allEvents.addAll(MyOrderEvents.values())
    allEvents.addAll(MyUserEvents.values())
    return allEvents
}

fun main() {
    scanForAllMyEventsInstances().forEach{e -> println(e.eventName)}
}

Но только один раз в классе. Каждое новое событие в этом классе распознается автоматически. Это нормально для меня.

примечание: val name не следует использовать при использовании класса enum, поскольку в классах enum значение name уже определено. Вот почему в MyEvent2 это называется eventName. Может быть, я даже могу пропустить name / eventName, потому что это 1: 1 к имени enum.

Я попробую с этим.

PS: Это все еще не хороший DSL , Я думаю. Но оптимизировать это я буду в будущем.

0 голосов
/ 24 февраля 2020

Я думаю, что enum class - ваш друг здесь.

enum class MyEvent(val eventName: String, val version: Int, val content: Map<String, String>) {
    OrderCreated("OrderCreated", 1, mapOf("orderId" to "UUID", "nameOfProduct" to "String(1, 256)", "quantity" to "Integer")),
    OrderCancelled("OrderCancelled", 2, mapOf("orderId" to "UUID", "reason" to "String(100, 1000)")),
    OrderQuestioned("OrderQuestioned", 3, mapOf("orderId" to "UUID", "question" to "String(10, 1000)"))
}

И вы можете перебирать экземпляры

MyEvent.values().forEach { println(it.eventName) }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...