Gavin
Gavin

Reputation: 2351

Modelling Related Objects

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

Answers (7)

chessguy
chessguy

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

Chris Cudmore
Chris Cudmore

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

Saif Khan
Saif Khan

Reputation: 18792

Agree with dacracot

Also look at DevExpress XPO

Upvotes: 0

dacracot
dacracot

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

Matthias Winkelmann
Matthias Winkelmann

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

Steven A. Lowe
Steven A. Lowe

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

Saif Khan
Saif Khan

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

Related Questions