Is it impossible to create immutable object graphs in some scenarios?

I know that immutability is not always the holy grail. However, since I have been studying Scala for quite some time, I always try to find an immutable solution first, especially when it comes to pure “data objects”. I am currently in search of a method for creating an immutable object graph for this scenario, but I'm not sure if this is possible at all.

I just want to create a chart once, no changes after creation are needed.

Imagine the following scenario:

  • There is only one type: Person.
  • Person objects can have two types of links:
    • there is a unidirectional 1-n connection between Person and potential children (also of type Person).
    • In addition, wives have husbands and vice versa

The first problem is that the relationship between the two spouses is cyclical. Since linking leads to new objects (due to immutability), ultimately spouse A points to spouse B_old, and spouse B points to spouse A_old. Someone in another publication said that circular references and immutability are oxymoron. I don’t think this is always true, since spouse A can create spouse B in her own constructor and go through this- but even with this inconvenient approach, adding child references will subsequently change A and B again. Another way - starting with children and then linking spouses - leads to a similar situation.

, , . , , , , . , ?

+4
2

, , , :

  • ,

, ( scala -way), :

object DeferredCycle extends App {

  class C(val name:String, _child: => C) {
    lazy val child = _child
    override def toString: String = name + "->" + child.name
  }

  val a:C = new C("A", b)
  val b:C = new C("B", a)

  println(a)
  println(b)
}

A->B
B->A
+4

, . , .

case class PersonId(id: Int)
case class Person(id: PersonId, name: String, spouse: Option[PersonId], children: Seq[PersonId])

val people: Map[PersonId, Person] = ...

, Person, :

case class PersonId(id: Int)
case class Person(id: PersonId, name: String)

val people: Map[PersonId, Person] = ...
val spouses: Map[PersonId, PersonId] = ...
val children: Map[PersonId, Seq[PersonId]] = ...
+2

Source: https://habr.com/ru/post/1612843/


All Articles