Использование классов сценариев Scala в качестве де-факто карт

Это больше вопрос дизайна, чем что-либо еще ...

Мне очень нравятся классы case в Scala, и я использую их Однако я обнаружил, что часто заключаю свои параметры в Options (или, скорее, Lift's Boxes ) и устанавливаю значения по умолчанию для обеспечения гибкости и учета того, что пользователь может не всегда указывать все параметры. Думаю, я перенял эту практику из.

Мой вопрос: разумен ли это? Учитывая, что все может быть необязательным, может быть много шаблонов и проверок, вплоть до того, является ли Интересно, не использую ли я только свои классы case, такие как Map [String, Any] , и задаюсь вопросом, не лучше ли мне просто использовать Map .

Пусть Приведу реальный пример. Здесь я моделирую денежный перевод:

case class Amount(amount: Double, currency: Box[Currency] = Empty)
trait TransactionSide
case class From(amount: Box[Amount] = Empty, currency: Box[Currency] = Empty, country: Box[Country] = Empty) extends TransactionSide
case class To(amount: Box[Amount] = Empty, currency: Box[Currency] = Empty, country: Box[Country] = Empty) extends TransactionSide
case class Transaction(from: From, to: To)

Думаю, относительно просто для понимания. В этом простейшем случае мы могли бы объявить T ransaction вот так:

val t = Transaction(From(amount=Full(Amount(100.0)), To(country=Full(US)))

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

val t2 = Transaction(From(Full(Amount(100.0, Full(EUR))), Full(EUR), Full(Netherlands)), To(Full(Amount(150.0, Full(USD))), Full(USD), Full(US)))

С другой стороны, несмотря на необходимость бросать Full повсюду, вы все равно можете выполнить хорошее сопоставление с образцом:

t2 match {
  case Transaction(From(Full(Amount(amount_from, Full(currency_from1))), Full(currency_from2), Full(country_from)), To(Full(Amount(amount_to, Full(currency_to1))), Full(currency_to2), Full(country_to))) if country_from == country_to => Failure("You're trying to transfer to the same country!")
  case Transaction(From(Full(Amount(amount_from, Full(currency_from1))), Full(currency_from2), Full(US)), To(Full(Amount(amount_to, Full(currency_to1))), Full(currency_to2), Full(North_Korea))) => Failure("Transfers from the US to North Korea are not allowed!")
  case Transaction(From(Full(Amount(amount_from, Full(currency_from1))), Full(currency_from2), Full(country_from)), To(Full(Amount(amount_to, Full(currency_to1))), Full(currency_to2), Full(country_to))) => Full([something])
  case _ => Empty
}

Разумный ли это подход? Могу ли я лучше воспользоваться картой ? Или мне следует использовать классы case, но по-другому? Возможно, использовать целую иерархию классов кейсов для представления транзакций с разным объемом информации?

8
задан paradigmatic 1 July 2011 в 13:32
поделиться