Scala:使用Trait + Companion对象枚举实现

时间:2019-05-16 21:36:57

标签: scala

我的问题是:这是反模式吗?

我有一个密封的scala特性,有十二个或两个实现-像这样说:

package com.erik.logic

sealed trait FailureReason {
  def why: String
}

case object A extends FailureReason {
  val why = "just because"
}
case class B(why: String) extends FailureReason
// ...
case object Z extends FailureReason {
  val why = "idk"
}

导入可能会变得很丑陋(根据我所阅读的大多数样式指南,开始使用._样式会变得很丑陋。)

一种选择是将它们全部放入特质的同伴对象中,然后我可以将其导入并以类似于枚举的方式进行引用。 这是反模式吗?< / strong>

package com.erik.logic

trait FailureReason {
  def why: String
}

object FailureReason
  case object A extends FailureReason { ... }
  case class B(why: String) extends FailureReason
  // ...
}

// otherFile.scala
import com.erik.logic.FailureReason

... reason match {
  case FailureReason.A => something
  case FailureReason.B(y) => other(y)
  case FailureReason.C => etc
}


// yetAnotherFile.scala
import com.erik.logic.FailureReason.{A, B, J, Q}

// ... badThing match {
  case SomethingBad => ReasonWrapper(A)
  case SomethingTerrible => ReasonWrapper(B("terrible"))
  case SomethingMeh => ReasonWrapper(Q)
}

1 个答案:

答案 0 :(得分:4)

这不是“反模式”,很好。您可以 顺便说一句,以相同的方式在包级别导入import com.erik.logic.{A, B, J, Q},因此无需将它们放入对象(但没有什么用)如果您仍然想这样做,也可能会出错)。

请注意,您应该将自己的特征定为sealed。这样,如果您忘记了一些case子句,而您的match并不详尽,则可以利用编译器警告您。