Как построить класс данных Kotlin из класса blueprint - PullRequest
0 голосов
/ 13 сентября 2018

В моем веб-приложении Spring Boot есть HTML-форма, которая заполняет объект Blueprint:

data class Blueprint(

    // relevant part, validation omitted
    var items: List<Long> = emptyList() // List of ids

    // ...
)

Позже я собираюсь использовать этот Blueprint для создания Product, который был бы классом данных аналогичной структуры:

data class Product(

    val items: List<Item>
    /* Here 'items' is a list of Item objects which are fetched from DB by */
    /* their ids. Item is data class too. */

)

Я бы хотел, чтобы Product принял объект Blueprint в качестве аргумента конструктора.

Я пытался перейти с вторичнойконструктор, но это требует от меня немедленного вызова первичного конструктора, прежде чем у меня появится возможность обработать проект и, возможно, отфильтровать некоторые идентификаторы элементов.

Конечно, есть обходные пути, такие как фабричная функция, но кажется,Разумно ожидать, что я могу просто передать проект конструктору.

Есть ли способ сделать это?

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Создайте вспомогательную функцию внутри сопутствующего объекта, которая предоставляет аргументы для основного конструктора. Затем вызовите этот помощник во вторичном конструкторе:

data class Product(val items: List<Item>) {
    constructor(blueprint: Blueprint)
            : this(makeItems(blueprint))

    private companion object {
        fun makeItems(blueprint: Blueprint): List<Item> {
            return blueprint.items
               .filter { ... }
               .map { Item(...) }
        }
    }
}

Если код конверсии короткий, вы, конечно, можете сделать это встроенным:

constructor(blueprint: Blueprint)
        : this(blueprint.items.filter { ... }.map { Item(...) })

Однако, поскольку вы имеете дело с data class, может быть более разумно предоставить фабрику fromBlueprint(), чтобы люди сразу увидели, что переданный аргумент не является свойством. В качестве альтернативы, вызовите конструктор с именованными аргументами, как Product(blueprint = ...).

0 голосов
/ 13 сентября 2018

Здесь у вас есть три варианта:

  1. Адаптер: Blueprint.asProduct()
  2. Заводской метод: Product.fromBlueprint(blueprint)
  3. Или просто: Product (blueprint.items.filter {/ * что-то здесь * /}

Это очень зависит от количества элементов между Product и Blueprint

Если у вас много классов Product,тогда иметь фабричный метод имеет больше смысла.

Если вы обычно создаете Product из Blueprint, тогда Adapter имеет больше смысла.

Если вы не можете понять это, третий вариант -также действует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...