С помощью Play Framework и класса с более чем 22 параметров


Я видел некоторые другие проблемы, связанные с печально известной проблемой" 22 поля/параметры", которая является неотъемлемой ошибкой (особенность?) Скала в здесь и здесь. Однако, согласно этому посту в блоге , кажется, что ограничение 22 параметра в case class было зафиксировано; по крайней мере, в том, что касается языка.

У меня есть case class, который я хочу загрузить произвольное (читай: > 22) число значений, в которое позже будет прочитано в объект JSON с помощью Play библиотека.

Это выглядит примерно так:

object L {
  import play.api.libs.json.Reads. _
  import play.api.libs.functional.syntax._

  implicit val responseRead: Reads[L] = (
    MyField1.jsPath.Read[MyField1.t] and 
    MyField2.jsPath.Read[MyField2.t] and
    ...
    MyField35.jsPath.Read[MyField35.t]
  ) (L.apply _)
}

case class L(myField1: MyField1.t, myField2: MyField2.t, ... myField35: MyField35.t)
Проблема в том, что при компиляции Scala жалуется, что в case class имеется более 22 параметров. (В частности: в последней строке определения объекта, когда компилятор пытается построить, я получаю: "реализация ограничивает функции до 22 параметров".) В настоящее время я использую Scala v2.11.6, поэтому я думаю, что это не языковая проблема. Это заставляет меня думать, что библиотека Play не обновила свою реализацию Read.

Если это так, то я думаю, что лучше всего сгруппировать связанные поля в кортежи и передать кортежи через API JSON?

2 2

2 ответа:

Как упоминалось в упомянутом вами посте в блоге, ограничение на 22 параметра все еще действует для функций в Scala 2.11 и более поздних версиях, поэтому то, с чем вы столкнулись , является языковой проблемой. Вызов функции в этом случае выглядит следующим образом:

L.apply _
Реструктуризация вашей модели - один из способов справиться с этим ограничением.

Таким образом, ответ на этот вопрос фактически состоит из двух частей:

1. Решение

Я назову это "обходным путем", потому что, хотя он и" работает", он обычно обращается к симптому, а не к проблеме. Мое решение состояло в том, чтобы использовать shapeless для предоставления общих гетерогенных списков произвольной длины. Это решение уже широко обсуждается и доступно в других местах. См., например, (1) [SO Post] Как обойти ограничение класса Scala case в 22 поля?; (2) блог почта; (3) Еще одна запись в блоге .

2. Решение

Как упоминает @jeffrey-chung, необходимо реструктурировать модель, чтобы справиться с этим ограничением. Как отмечали многие в отрасли, наличие функции с более чем 30 аргументами, скорее всего, означает, что ваша функция делает слишком много или что функция должна быть рефакторизована, чтобы принять меньшее количество аргументов. См., например, (1) правило 30-когда метод, класс или подсистема слишком велики?; (2) стиль Дэбрика руководство .