tags:

views:

84

answers:

6

I need help trying to figure out the proper design of my classes.

I have a user class:

class AppUser:
    _email - String
    _fullname - String
    _organizations - List of ????
    _active - Boolean
    ------------------
    getOrgs - Method

Also, I have an Organizations class:

class Organization:
    _name - String
    _domain - String
    _members - List of ????
    ------------------
    getMembers

So, my issue is the Lists. The Org class has a list of _members. This list should probably be a list of AppUser objects. And, the AppUser class has a list of _organizations. This list should probably be a list of Organization objects.

But this would create a circular reference.

So, how should I implement this?

Edit: Need to implement this using Python.

A: 

I would take a look at many to many relationships and 3rd form normalization

sarcasteak
+1  A: 

You did not specify which language you were using. That is important because in some languages circular references do cause problems (VB6) while in others they do not (Java, C#, etc.). In most cases you will be okay with circular references in your class hierarchies especially if you are using a modern language that uses garbage collection for memory management.

Brian Gideon
e.g., the bidirectional dependency between classes is fine in C# _within a single project_, but disallowed in C or C++ (without certain techniques...).
apollodude217
@apollodude217: Its actually okay to do cross assembly references in C# as well as long as that bidirectional dependency is done through an indirect link from a type defined in 3rd assembly.
Brian Gideon
+1  A: 

this is called a many-to-many association. you should also consider if you need bi-directional navigatability

Pangea
+1  A: 

I don't see a problem with each respective class having the references you've mentioned - it's how many domain models work with 1:n relationships.

So your class could look like this (C#):

public class AppUser {
public string Email { get; set;}
public string FullName { get; set;}
public bool Active { get; set;} 
public List<Organization> Organizations { get; set;} //... and so on
}

public class Organization {
public string Name { get; set;}
public string Domain { get; set;}
public List<AppUser> Members { get; set;} //... and so on
}
Josh E
A: 

An important distinction to make is that in most modern languages, lists of objects are by reference (pointers), not by value. This means that you can have members point to groups, and groups point to members. If you everything was a value, you would indeed have a circular reference - every group would try and keep its own copy of all of its members, which would try and keep its own copy of all of its groups, etc.

Daniel Rasmussen
A: 

To avoid duplication, overall, I think the Set is probably the data structure of choice.

Using the AppUser in the Set of members in the organization probably is the right call.

There is nothing wrong with having a bidirectional relationship with entities, they just require a bit of thought and planning.

The important thing to be mindful of is which entity controls the relationship so that when you go to add an AppUser to an Organization you do not end up in an infinite loop of additions by trying to use the addOrganization to an AppUser, which then tries to add that user to the organization, etc.

apiri