Есть ли способ использовать систему типов Scala для краткого указания контекстно-значимого подграфа полного графа объектов?
DCI утверждает, что у вас часто есть довольно сложный граф объектов, но в любом случаеЕсли вы часто хотите работать только с подграфом.У вас есть Foo
, который имеет Bar
и Bat
, но когда вы используете вариант использования 1, вы заботитесь только о Bar
, а в случае использования 2 - только о Bat
.
Например, предположим, что у вас есть эта структура, а сценарий использования Role1 требует Foo->Bar->Baz->Bin
, а сценарий использования Role2 требует 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
для доступа к bin
и BazInRole2
для доступа к 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 достаточно выразительна, чтобы делать что-то подобное, но я не могу понять это.