Reputation: 2351
I'm designing an application which deals with two sets of data - Users and Areas. The data is read from files produced by a third party. I have a User class and an Area class, and the data is read into a Users array and an Areas array (or other appropriate memory structure, depending on the technology we go with).
Both classes have a unique ID member which is read from the file, and the User class contains an array of Area IDs, giving a relationship where one user is associated with many Areas.
The requirements are quite straightforward:
My first thought was to leave the data in the two arrays, then for each of the requirements, have a seperate method which would interrogate one or both arrays as required. This would be easy to implement, but I'm not convinced it's necessarily the best way.
Then I thought about having a 'Get Areas' method on the User class and a 'Get Users' member on the Area class which would be more useful if for example I'm at a stage where I have an Area object, I could find it's users by a property, but then how would a 'Get Users' method on the Area class be aware of/have access to the Users array.
I've had this problem a number of times before, but never really came up with a definitive solution. Maybe I'm just making it more complicated than it actually is. Can anyone provide any tips, URLs or books that would help me with this sort of design?
UPDATE: Thank you all for taking your time to leave some tips. Your comments are very much appreciated.
I agree that the root of this problem is a many-to-many relationship. I understand how that would be modelled in a relational database, that's pretty simple.
The data I receive is in the form of binary files from a third party, so I have no control over the structure of these, but I can store it whichever way is best when I read it in. It is a bit square pegs in round holes, but I thought reading it in then storing it in a database, the program would then have to query the database to get to the results. It's not a massive amount of data, so I thought it would be possible to get out what I need by storing it in memory structures.
Upvotes: 3
Views: 342
Reputation: 478
One option is to use a dictionary for each of the last 2 requirements. That is, a Dictionary<Area, List<User>>
and a Dictionary<User, List<Area>>
. You could build these up as you read in the data. You might even wrap a class around these 2 dictionaries, and just have a method on that class for each of the requirements. That would allow you to make sure the dictionaries stay in sync.
Upvotes: 0
Reputation: 30151
Very basic, but the idea is:
struct/class Membership
{
int MemberID;
int userID;
int areaID;
}
This class implements the "user belongs to area" membership concept. Stick one of these for each membership in a collection, and query that collection for subsets that meet your requirements.
EDIT: Another option
You could store in each Member a list of Areas, and in each Area, a list of Members.
in Area:
public bool addMember(Member m)
{
if (/*eligibility Requirements*/)
{
memberList.add(m);
m.addArea(this);
return true;
}
return false;
}
and a similar implementation in Member (without the callback)
The advantage of this is that it's pretty easy to return an iterator to walk through an Area and find Members (and vice versa)
The disadvantage is that it's very tightly coupled, which could cause future problems.
I think the first implementation is more LINQ friendly.
Upvotes: 3
Reputation: 22348
I'm sorry, but this is not an object-oriented problem. It is a relational problem. Hence all the references to cardinality (many-to-many). This is relational database modeling 101. I don't mean to criticize Gavin, just to point out a new perspective.
So what good is my rant. The answer should be to integrate with a relational data store, not to pound it into a object oriented paradigm. This is the classic square peg, round hole issue.
Upvotes: 1
Reputation: 16394
Does an area belong to multiple users? If yes, it's a technically a many-to-many relationship. If you were to transform the data into a relational database, you'd create a table with all the relationships. I guess if you want to work with arrays, you could create a third array. Or if you actually want to do this in an OO way, both classes should have arrays of pointers to the associated areas/users.
Upvotes: 2
Reputation: 61233
this is really a many-to-many relationship,
User <<--->> Area
break it up into 3 objects, User, Area, and UserArea:
User: Id, name, etc.
Area: Id, name, etc.
UserArea: UserId, AreaId
Upvotes: 7
Reputation: 18792
Why not use DataTables with relations, if .NET is involved? You may want to look into Generics as well, again, if .NET is involved.
Upvotes: 0