|Pathologically Eclectic Rubbish Lister|
One to many, many to one relationshipsby rvosa (Curate)
|on Mar 12, 2007 at 02:10 UTC||Need Help??|
rvosa has asked for the
wisdom of the Perl Monks concerning the following question:
I am debating how best to design the following: I have three types of objects ($nodes in evolutionary trees, DNA $sequences, and $taxon objects, i.e. "species"). I want to create bi-directional relationships between these things.
For example, the $taxon object (being a representation of our concept of a "species") with the name 'Homo sapiens' could be instantiated at some point, and subsequently a $sequence object containing a human DNA sequence could be created. I want to create a link between the sequence and the taxon. In fact, I might want to link many sequences to that one taxon (say, a set of genes sequenced from a human subject), and link many nodes (from different trees) to that one taxon. Simply put: there's a one-to-many relationship from taxon to nodes and sequences, and a one-to-one relationship from node to taxon, and from sequence to taxon.I now wonder if I should create a $taxonlinker object that does the bookkeeping in both directions, e.g. $taxonlinker->make_link( $node, $taxon ) or something to that effect, and all other objects ($nodes, $sequences and $taxon objects) simply communicate with the bookkeeper and ask it for whatever else might be on the other side of the link.
The end result should be that I can do things like:
I have so far used a design where the nodes and sequences have a set_taxon method (where the ref to the taxon is stored as a field in the object), and the taxon objects have set_nodes and set_sequences methods (also with fields for those, directly in the object). This strikes me as bug prone, because all the relationships automatically have to be bidirectional.
The quick fix is to say that whoever is called to set_whatever needs to check whether or not the link in the other direction exists, and make one if not. Then, you have to prevent these calls from bouncing back and forth, and pretty soon you're in if/elsif/elsif... territory.
I half and half got that idea from perldesignpatterns but the page doesn't give me that much. Could anyone give some examples how that might work in the wild? Some code?