完全なオブジェクト グラフのコンテキスト関連サブグラフを簡潔に指定するために Scala の型システムを使用する方法はありますか?
DCI は、多くの場合、かなり複雑なオブジェクト グラフを使用しているが、どのユース ケースでも、サブグラフのみを操作したい場合が多いと主張しています。と を持つ がFoo
ありBar
ますBat
が、ユースケース 1 の場合は のみを気Bar
にし、ユースケース 2 の場合はのみを気にしBat
ます。
たとえば、この構造があり、Role1 ユースケース requiresFoo->Bar->Baz->Bin
と Role2 ユースケース requiresがあるとしFoo->Bat->Baz->Buz
ます。
class Foo{
val bar = new Bar() //Only relevant to Role 1
val bat = new Bat() //Only relevant to Role 2
}
class Bar {
val baz = new Baz()
}
class Bat {
val baz = new Baz()
}
//Relevant to both Role 1 and 2 (via Bar or Bat)
class Baz {
val bin = new Bin() //Only relevant to Role 1
val buz = new Buz() //Only relevant to Role 2
}
class Bin{}
class Buz{}
特性を使用して、単一のクラスでアクセスを制限する方法を簡単に確認できます。
trait FooInRole1 { def bar : Bar } //Define accessor in trait
s/Foo/Foo extends FooInRole1/ //Change Foo's declaration to implement trait
val f : FooInRole1 = new Foo //LHS is i'face, RHS is implementation
//f.bat <--Compile error Irrelevant field is not available. \o/
ただし、ユースケースに関連するすべてのオブジェクトに対してこのパターンを繰り返す必要があります。(たとえば、BazInRole1
to accessbin
とBazInRole2
to access が必要ですbiz
)
私の質問は、これらの間違いやすい、名前空間が密集している特性をすべて記述することを回避する方法があるかどうかです。たとえば、次のようなコード (コンパイルされない) を想像できます。
class Foo[T] {
T match {
case r1 : Role1 => def bar : Bar[T]
case r2 : Role2 => def bat : Bat[T]
case _ => //Nothing
}
}
val fInRole1 = new Foo[Role1] //Provides Foo->Bar->Baz->Bin
val fInRole2 = new Foo[Role2] //Provides Foo->Bat->Baz->Buz
Scala の型システムはこのようなことを行うのに十分な表現力があるようですが、私にはわかりません。