Dear monks,

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.

The end result should be that I can do things like:
my @sequences = $taxon->get_sequences; my @nodes = $taxon->get_nodes; my $taxon = $node->get_taxon;
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 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.

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?

Thanks!

In reply to One to many, many to one relationships by rvosa

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.