Reputation: 1124
What is the way to design software in functional way, when there are dependencies between objects?
class Link(val name: String, val links: Vector[Link] = Vector()){
def changeName(newName: String): Link = {
new Link(newName, links)
}
def connect(other: Link): Link = {
new Link(name, links :+ other)
}
}
object Main
{
def main(args: Array[String]): Unit = {
val A = new Link("A")
val B = new Link("B")
val Alinked = A connect B
val updatedB = B changeName "B2"
println(Alinked.links.contains(updatedB))
}
}
Output
false
I connect A and B, but then B is being changed. It implies, that I have to reconnect new object to previous. In complex hierarchies it can get really hard to control such updates.
How to make automatical relinking? Delegates? Actors?
Upvotes: 3
Views: 95
Reputation: 67310
If you need to keep the identity of immutable copies of objects together, I think one solution is to introduce a unique identifier:
case class Link(id: Int)(val name: String, val links: Vector[Link] = Vector()) {
def changeName(newName: String): Link =
new Link(id)(newName, links)
def connect(other: Link): Link =
new Link(id)(name, links :+ other)
}
def test(): Boolean = {
val A = Link(0)("A")
val B = Link(1)("B")
val Alinked = A connect B
val updatedB = B changeName "B2"
Alinked.links.contains(updatedB)
}
assert(test())
That is, once an object is created, you carry the same id
across all copies. The case class
here makes sure that equals
is correctly defined by looking at the id
field.
Upvotes: 1