設計對我來說看起來不錯,但不推薦擴展案例類。原因簡單總結爲什麼可以在這裏找到:https://stackoverflow.com/a/12705634/2186890
所以你可能要重寫Feature
因爲這樣的事情:
trait Feature { def value: String }
現在,你可以定義模式匹配等這樣的情況下,類:
case class CountedFeature(value: String, count: Long) extends Feature with Counted
有沒有簡單的方法來避免case類這樣的組合爆炸,但你啓動你喜歡的地方使用類型,如Feature with Counted
。請記住,您可以輕鬆創建匹配類型Feature with Counted
的對象。例如:
val x: Feature with Counted = new Feature with Counted { val value = ""; val count = 0L }
實施computeWeightsByCount
像你想要的是一個有點棘手,因爲沒有簡單的方法來建立一個T with Weighted
不知道更多關於T
型。但它可以用隱式方法完成。實質上,我們需要有一個定義的路徑,用於從T
中爲您想要應用此方法的每個Feature with Counted
生成T with Weighted
。例如,我們開始與此:
trait Feature { def value: String }
trait Counted { def count: Long }
trait Weighted { def weight: Double }
trait Indexed { def index: Int }
我們要定義computeWeightsByCount
就像你在你的問題做了,但是也考慮採用一個T
和重量的隱式方法,併產生一個T with Weighted
:
def computeWeightsByCount[
T <: Feature with Counted](
features: List[T])(
implicit weighted: (T, Double) => T with Weighted
): List[T with Weighted] = {
def weight(fc: Feature with Counted): Double = 0.0d
features map { f => weighted(f, weight(f)) }
}
現在我們需要定義一個隱式方法來根據輸入要素產生加權特徵。我們從Feature with Counted
開始獲得Feature with Counted with Weighted
。我們會把它放在同伴對象Feature
:
object Feature {
implicit def weight(fc: Feature with Counted, weight: Double): Feature with Counted with Weighted = {
case class FCW(value: String, count: Long, weight: Double) extends Feature with Counted with Weighted
FCW(fc.value, fc.count, weight)
}
}
我們可以使用它像這樣:
case class FC(value: String, count: Long) extends Feature with Counted
val fcs: List[Feature with Counted] = List(FC("0", 0L), FC("1", 1L))
val fcws: List[Feature with Counted with Weighted] = computeWeightsByCount[Feature with Counted](fcs)
對於要計算的加權數的任何類型,你需要定義一個類似這種隱式方法。
無可否認,這遠非一個美麗的解決方案。所以是的,你是對的,你可能想重新考慮設計。然而,這種方法的好處是可以在不需要對computeWeightsByCount
進行任何修改的情況下對Feature
「層次結構」進一步擴展。無論誰寫新的特質,都可以提供合適的隱含方法。