Esto es más una cuestión de diseño que cualquier otra cosa ...Uso de clases de casos de Scala como mapas de facto
Me gustan mucho las clases de casos de Scala y las uso a menudo. Sin embargo, me parece que a menudo estoy envolviendo mis parámetros en Options
(o mejor dicho, Lift's Boxes
) y estableciendo valores predeterminados para permitir flexibilidad y dar cuenta de que un usuario no siempre puede especificar todos los parámetros. Creo que adopté esta práctica de.
Mi pregunta es, ¿es este un enfoque razonable? Dado que todo puede ser opcional, puede haber un montón de repetición y verificación, hasta el punto de que me pregunto si no estoy usando mis clases de casos como Map[String, Any]
y me pregunto si no sería mejor usar un Map
.
Déjeme darle un verdadero ejemplo. Aquí estoy modelando una transferencia de dinero:
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)
Relativamente simple de entender, creo. En este simple podríamos declarar una Transaction
así:
val t = Transaction(From(amount=Full(Amount(100.0)), To(country=Full(US)))
ya que puede imaginar usted piensa que es prolijo. Y si especificamos todo:
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)))
Por otro lado, a pesar de tener que tirar Full
por todas partes, todavía se puede hacer algo agradable coincidencia de patrones:
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
}
Es este un enfoque razonable? ¿Me serviría mejor usando un Map
? ¿O debería usar clases de casos pero de una manera diferente? ¿Tal vez usando una jerarquía completa de clases de casos para representar transacciones con diferentes cantidades de información especificadas?
Gracias por el enlace a la charla de Lentes, lo estoy escuchando ahora. ¿Pero hay páginas web con un tutorial? Me gustaría aprender más! – pr1001
Nunca los encontré para scala, pero debería existir para haskell. – paradigmatic