2013-03-24 82 views
0

我試圖使用斯卡拉的蛋糕模式與通用攔截器與多組(層)的那些。當一個圖層的末尾需要另一個圖層時,我嘗試使用自我類型來表示該圖層。但是它違反了非法繼承。該任務的一般背景是我有一個文檔模型,我正在試圖進行驗證鏈。玩具示例如下,每層僅由一個特徵表示。斯卡拉通用自我類型不匹配

trait Element 
trait Leaf extends Element 
trait Composed extends Element 

trait Validator [A] {def validate (element : A) : String} 

//second layer 
trait LeafValidator extends Validator[Leaf]{ 
    override def validate (element : Leaf) : String = "leaf"} 

//first layer 
trait ElementValidator extends Validator[Element]{ 
    self : Validator[Leaf] => 

    override def validate (element : Element) : String = element match { 
    case leaf : Leaf => super.validate(leaf) 
    case _ => "other" 
    } 
} 

case class Concrete extends LeafValidator with ElementValidator 

的錯誤是在實例化線

非法遺傳;自我類型apltauer.david.util.Concrete不符合apltauer.david.util.ElementValidator的自定義apltauer.david.util.ElementValidator和apltauer.david.util.Validator [apltauer.david.util.Leaf] Main.scala /依賴/ src/apltauer/david/util line 56 Scala問題

逆變抑制了錯誤,但並沒有解決問題,因爲自我類型沒用。

+0

這不是一個蛋糕模式,你只是使用自我型註釋。我會推薦在這裏使用組合。 – 2013-03-24 21:02:40

+0

只要將這些圖層展開成多個特徵,它就會成爲蛋糕圖案。也許關於蛋糕模式的信息實際上並不那麼重要。我讚賞不同的設計方案,但我仍然想解決這個謎團。 – 2013-03-24 21:07:38

+2

給定的類不能實現用兩種不同類型參數化的(非變體)接口:Foo不能同時擴展Bar [A]和Bar [B]。 – 2013-03-24 21:29:51

回答

0

我有同樣的問題。使用兩種特徵變體會破壞(否則,很好且有用的)蛋糕模式。

所以我開發了一個增強功能,它涉及我的問題,允許我保持蛋糕圖案完好無損,並且我稱之爲特徵模式。你的情況:

trait element_validator extends validator[Element] { 
    final override val element_validator = this 
} 
trait feature_element_validator { val element_validator : element_validator } 

/* Analogous for 「Leaf」 */ 

trait validator[element_type] { 
    final override val validator = this 
    /* Feature code here: */ 
    def validate(element: element_type) = /* … */ 
} 
trait feature_validator[element_type] { val validator : validator[element_type] } 

所以,現在我們可以說:

object component 
    extends element_validator 
    with leaf_validator 
    with other_cake_feature_1 
    with other_cake_feature_2 
    with other_cake_feature_3 
    /* etc. */ 

內部組件一會區分兩種驗證的:

element_validator.validate(…) 
leaf_validator.validate(…) 

如果只有一個要求,然後導入(這與使用自我類型註釋獲得姓名的效果相同):

import element_validator._ 
validate(…) 

我知道,這是一些樣板。然而,我沒有看到任何其他的解決方案,而不是將蛋糕與成分結合在一起(無論何時需要組成)。