2013-03-24 77 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(…) 

我知道,这是一些样板。然而,我没有看到任何其他的解决方案,而不是将蛋糕与成分结合在一起(无论何时需要组成)。