Это больше вопрос дизайна, чем что-либо еще ...
Мне очень нравятся классы 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, но по-другому? Возможно, использовать целую иерархию классов кейсов для представления транзакций с разным объемом информации?