0

Assume, we have classes A_1 to A_n and classes B_1 to B_n.

Each A_i has relationships (abstract spoken; a relation could be 'A_4 likes B_2') to a set of B_j's and the same the other way round.

Question: Where is a good place to store the relationship information ? Is there a good pattern for this kind of problem ?

Solution 1: Each A_i has a list field store the B_j's it has a relation with.

Solution 2: Each B_i has a list field store the A_j's it has a relation with.

Solution 1 and 2 are basically the same.

Solution 3: Store the information in a third 'information' class, e.g. as a matrix.

Charles
  • 50,943
  • 13
  • 104
  • 142
John Threepwood
  • 15,593
  • 27
  • 93
  • 149
  • 2
    It depends. But what I find strange is your set of classes. Shouldn't you have a class A, a class B, and multiple instances of A and B? – JB Nizet Jul 21 '12 at 13:29
  • The 3rd solution looks quite nice if you think a bit you could have an abstract class named `Relation` and another class `Like` that would have both part composing the relation (A and B) and properties. +1 to JBNizet's comment – Francisco Spaeth Jul 21 '12 at 13:29
  • I take it from your description that all relationships are bidirectional? – Keppil Jul 21 '12 at 13:36
  • @JBNizet In my case, I actually deal with subclasses which have relations. So each object of class `A_i` will always be in relation with the same `B_j`'s. – John Threepwood Jul 21 '12 at 13:41
  • @Keppil No, the relation is a one-direction relation. Solution 2 is basically the same as 1, because the `B_j` could also store the classes of `A_i`'s which like `B_j`. – John Threepwood Jul 21 '12 at 13:42

1 Answers1

1

No matter which one you choose between Solution 1 and Solution 2 some information about what a class likes is only stored in another class, which seems a bit backwards.
Therefore, I would definitely go for a separate RelationKeeper class, something like this:

public enum RelationType {
    LIKES,HATES...
}
public class Relation {
   RelationType type;
   Class relatedClass; //Or in what type and form this is stored
}
public class RelationKeeper {
   public List<Relation> getRelationsFor(Class c) {
   }
   public void setRelationsFor(Class c, List<Relation> relations) {
   }
   public void addRelationFor(Class c, Relation relation) {
   }
   ...etc
}

This way you can customize and change the internal storage method to fit your needs, depending on if you want to be able to retrieve only "outgoing" relations of a class or if you also want to be able to fetch "inbound" relations.

Keppil
  • 45,603
  • 8
  • 97
  • 119