0

複数のグループ (レイヤー) を持つ汎用インターセプターで Scala のケーキ パターンを使用しようとしています。あるレイヤーの最後に別のレイヤーが必要な場合は、self タイプを使用してそれを表現しようとします。しかし、不正な継承で失敗します。タスクの一般的なコンテキストは、一連の検証を実行しようとしているドキュメント モデルを持っていることです。おもちゃの例では、各層が 1 つの特性だけで表されます。

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

エラーはインスタンス化行にあります

違法な相続; self-type apltauer.david.util.Concrete は apltauer.david.util.ElementValidator の selftype apltauer.david.util.ElementValidator と apltauer.david.util.Validator[apltauer.david.util.Leaf] Main.scala / Dependency/src/apltauer/david/util 行 56 Scala の問題

反変性はエラーを抑制しますが、self 型は役に立たないため、問題は解決しません。

4

1 に答える 1

0

私も同じ問題を抱えていました。機能の 2 つのバリアントを使用すると、(それ以外の場合は便利で便利な) ケーキ パターンが壊れます。

そこで私は拡張機能を開発しました。これにより、私の問題に関して、ケーキ パターンをそのまま維持できるようになりました。これをFeature Patternと呼びます。あなたの場合:

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. */

コンポーネント 1 の内部では、2 種類のバリデータが区別されます。

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

1 つだけが必要な場合は、インポートします (名前の可用性のために self-type-annotation を使用するのと同じ効果があります):

import element_validator._
validate(…)

私は知っています、それはかなりのボイラープレートです。ただし、ケーキとコンポジションを組み合わせる以外の解決策はありませんでした(コンポジションが必要な場合はいつでも)。

于 2015-07-03T13:54:50.010 に答える