https://kotlinlang.org logo
#getting-started
Title
# getting-started
t

Travis Griggs

11/28/2023, 12:03 AM
Kotlin OO question. It's usually undeseriable to have circular pointers from a design pov (parent has a child propoery, and child has a property for parent), but sometimes its inevitable. Composing with pluggable strategies can do that. But I'm finding that the constructor logic gets kind of circular. So given in A and a B, each with a property for b and a respectively, what's the best way to instantate that releationship? And it can be the same for the lifecycle of the object (doesn't need to be a var)
What I'd like to do be able to do actually, is construct/init the parent class with a class/type indicating what the pluggable strategy is (which is one of a sealed class heirarchy) so that the parent can instantiate the strategy and set up the ciruclar linkage
d

Daniel Pitts

11/28/2023, 1:54 AM
So you have a Container class and Content, you want Container to have-a Content, and Content to have-a Container? Is this always a 1:1 set up, or is it 1:n or n:m?
Ideally, you wouldn't even have circular types, meaning that the Content class doesn't know a thing about the Container class. If you need to expose the behavior from the Container to the Content, then it'd be better to separate out the interfaces for those behaviors.
Sometimes there is a completely different abstraction that makes these kinds of OOP problems go away, and you just need to think about it from a different angle.
c

Casey Brooks

11/28/2023, 5:46 PM
Keeping those relationships directly in the A and B classes will necessarily require one or the other to be a mutable property, which certainly isn’t ideal. From a Kotlin perspective, I’d argue that it’s not the circular references that are problematic, it’s the fact that they’re mutable properties. One alternative would be to use a 3rd structure to manage the relationships. A and B are just normal, immutable classes, while that 3rd class contains the mappings from parent-to-child, and each node can query that mapping to determine its parent, ancestors, children, etc. It’s essentially just a Graph data structure where you store nodes and edges independently of one another, or like a relational DB using an extra table for a many-to-many join.
Another alternative is to give each node an ID and store only the ID of the parent/children in each node, rather than storing the actual node reference. Again, you’d use another structure to hold the nodes, and each node can then query that class to get the related nodes by their IDs.