Это больше вопрос дизайна, чем что-либо еще ...
Мне действительно нравятся тематические классы Scala, и я часто их использую. Однако я нахожу, что я часто оборачиваю свои параметры в Options
(точнее, в Lift Boxes
) и задаю значения по умолчанию, чтобы обеспечить гибкость и учесть, что пользователь не всегда может указывать все параметры. Я думаю, что я принял эту практику от.
Мой вопрос: это разумный подход? Учитывая, что все может быть необязательным, может быть много шаблонов и проверок, вплоть до того, задаюсь ли я вопросом, не использую ли я просто свои классы дел, такие как 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)
Относительно просто для понимания, я думаю. На самом простом мы можем объявить Transaction
примерно так:
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
}
Это разумный подход? Буду ли я лучше обслужен с помощью Map
? Или я должен использовать тематические классы, но по-другому? Возможно, используя целую иерархию классов дел для представления транзакций с указанным количеством информации?