2012-04-21 11 views
6

Mam klasy marka, która kilka produktówScala: jak model podstawowy relacji rodzic-dziecko

A w klasie produktów Chcę mieć odniesienie do marki, na przykład:

case class Brand(val name:String, val products: List[Product]) 

case class Product(val name: String, val brand: Brand) 

Jak mogę odgrodzić te klasy ???

To znaczy, że nie można stworzyć produkt, chyba muszę marka

I nie mogę stworzyć markę, chyba mam listę produktów (bo Brand.products jest val)

Jaki byłby najlepszy sposób modelowania tego rodzaju relacji?

Odpowiedz

6

Chciałbym zakwestionować, dlaczego powtarzasz informacje, mówiąc, które produkty odnoszą się do marki na obu listach i w każdym produkcie.

Mimo to, można to zrobić:

class Brand(val name: String, ps: => List[Product]) { 
    lazy val products = ps 
    override def toString = "Brand("+name+", "+products+")" 
} 

class Product(val name: String, b: => Brand) { 
    lazy val brand = b 
    override def toString = "Product("+name+", "+brand.name+")" 
} 

lazy val p1: Product = new Product("fish", birdseye) 
lazy val p2: Product = new Product("peas", birdseye) 
lazy val birdseye = new Brand("BirdsEye", List(p1, p2)) 

println(birdseye) 
    //Brand(BirdsEye, List(Product(fish, BirdsEye), Product(peas, BirdsEye))) 

według nazwy params nie wydają się być dozwolone dla klas przypadków niestety.

Zobacz także to podobne pytanie: Instantiating immutable paired objects

+0

Naprawdę wydaje się, czego szukam, próbowałem go na repl i mówi mi, że birdseye nie znaleziono, musiałem użyć trybu: paste i wszystko działało dobrze, ale jak powiedziałeś, klasa przypadku nie jest obsługiwana :-( – opensas

+0

Dodałem odniesienie do marki, aby móc ją przemierzać w obie strony, ale myślę, że w podejściu funkcjonalnym przynosi więcej bólów głowy niż korzyści ... Mam rację? – opensas

+0

@opensas it jest trochę bóle głowy, ale czasami konieczne, w przeciwnym razie musisz użyć 'var's dla pól i ryzyko' null's, ale ta wersja jest bezpieczna –

3

Ponieważ Twoje pytanie jest o modelu do tej relacji, powiem, dlaczego nie tylko modelować je jak to, co robimy w bazie danych? Oddziel encję i relację.

val productsOfBrand: Map[Brand, List[Product]] = { 
    // Initial your brand to products mapping here, using var 
    // or mutable map to construct the relation is fine, since 
    // it is limit to this scope, and transparent to the outside 
    // world 
} 
case class Brand(val name:String){ 
    def products = productsOfBrand.get(this).getOrElse(Nil) 
} 
case class Product(val name: String, val brand: Brand) // If you really need that brand reference 
Powiązane problemy