¿Existe alguna manera de utilizar el sistema de tipos de Scala para especificar concisamente el subgráfico relevante al contexto de un gráfico de objetos completo?¿Puede Scala restringir un gráfico de objetos para que solo estén visibles los objetos relevantes para el contexto?
DCI argumenta que a menudo tiene un gráfico de objetos bastante complejo, pero en cualquier caso de uso, a menudo solo quiere trabajar con un sub-gráfico. Tiene un Foo
que tiene un Bar
y un Bat
, pero cuando está en el caso de uso 1, solo le importa el Bar
y cuando está en el caso de uso 2, solo sobre el Bat
.
Por ejemplo, digamos que usted tiene esta estructura, y el uso de los casos role1 requiere Foo->Bar->Baz->Bin
y Role2 caso de uso requiere 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{}
Es fácil ver cómo se puede restringir el acceso en una sola clase mediante el uso de rasgos:
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/
Pero usted tiene que repetir este patrón para cada objeto relevante para el uso- caso. (Por ejemplo, se necesita un BazInRole1
acceder a bin
y una BazInRole2
acceder a biz
)
Mi pregunta es si hay alguna manera de evitar la escritura de todos estos rasgos fácil de conseguir-mal, de espacio de nombres de hacinamiento. Por ejemplo, yo podía imaginar algo así como el código (que no compila):
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
Parece que tipo de sistema de Scala es lo suficientemente expresivo para hacer algo como esto, pero no puedo entenderlo.
Creo que se puede lograr algo como esto con las clases de tipo. Simplemente haga que la clase-tipo sea la vista en el gráfico del objeto y acceda y manipule su contenido solo a través de la clase-tipo. – ziggystar