Monday, March 26, 2012

OO Design question

Hi,

I'm tangling with my first "proper" OO application design at the moment. Unsurprisingly it's causing me major headaches!

The current question that's occuping me is this. The app in questionhandles traffic to our various secure extranets. In this applicationthere's a User object and an Extranet object. Currently the User has anindexed Arraylist which contains a list of the Extranets they haveaccess to. However, there are different levels of access possible andone user may be an admin for one extranet, a user on another and aguest on another and so on.

Having logged in, the user is presented with a list of Extranets theycan access, which is generated by looping through this indexedArraylist. However, I'd really like to have the access level printedalongside. I have not the faintest idea how best to design my objectsto achieve this. I can't use an Arraylist, obviously as it's only onedimensional. Should I be using a collection? A collection of Extranetobjects? A multidimensional indexed array (is such a thing possible)?

I'm confused also in the User/Extranet object relationship as to howthis access level fits in. Is it a property of User or Extranet?

Help!

Hello mattt:

> I'm confused also in the User/Extranet object relationship as to how this access level fits in. Is it a property of User or Extranet?

Technically speaking, it is a property of their relationship. It might be designed as something like:

[User] --access--> [User_Extranet] <--accessed-- [Extranet]

and that access level attribute belongs to the User_Extranet class.

> I can't use an Arraylist, obviously as it's only one dimensional. Should I be using a collection? A collection of Extranet objects? A multidimensional indexed array (is such a thing possible)?

Well, i guess you need a custom class for the User_Extranet. This said, an ArrayList can hold object references, so you can have an ArrayList of User_Extranet. Even better, if you are on .NET 2, you can use a generic collection class from the System.Collections.Generic namespace.

Hope this can be a starting point. -LV


Here's how I would design it:

Object User has a Collection of Extranet objects. The Extranet object has a property called Access of type enum and the enum should contain all possible access rights.

if (User.Extranet[0].AccessRight == AccessRight.Admin){//he's an admin}
There's my 2 cents.

jstawski:

Object User has a Collection of Extranet objects. The Extranet object has a property called Access of type enum and the enum should contain all possible access rights.

It's an n-to-n relationship between User and Extranet. If you just assign the 'access level' to the Extranet class, how can you tell the access right for different users? (Two different users, two different access rights for the same extranet.)

-LV


I agree. A many to many relationship on the DB. When it comes to the OO design, it depends on how you look at the problem. If you're never going to go from extranet to user then you don't care about extranet.users. That depends on a business need.


jstawski:

I agree. A many to many relationship on the DB. When it comes to the OO design, it depends on how you look at the problem. If you're never going to go from extranet to user then you don't care about extranet.users. That depends on a business need.

No no, i'm talking about class/object relationships there, that is OO modeling. There are many-to-many relationship in OO as well, usually modeled as relationship attributes in conceptual modeling, then implemented with a crossing class in design.

Theory apart, as i've already tried to point out: "If you just assign the 'access level' to the Extranet class, how can you tell the access right for different users?" Say for the same extranet, you can't tell user A has role X and user B has role Y if you just have that as an attribute for the extranet class...

-LV


LudovicoVan:

Technically speaking, it is a property of their relationship.

Thanks for this suggestion. I took a look at some UML references and discovered they refer to this as an "association class". The theory seems perfectly straightforward - it's just like a link table in a relational database. And yes, there most definately is a many-to-many relationship between User and Extranet although whether I'd ever need the admin level going from Extranet to User is debatable. But I'd like to get the design right, just in case.

However I'm a bit stumped as to how you'd actually represent an association class in code. I mean I presume it'd need properties to represent the User, the Extranet and the Admin level but how do I actually use all three objects together to achieve my goal - listing the extranets available to a user with the admin level alongside?

Cheers,

Matt


Matt:

>> Technically speaking, it is a property of their relationship.
> I took a look at some UML references and discovered they refer to this as an "association class".

Yes, that's it. Btw, an "association" isn't but one kind of "relationship" among others.

> whether I'd ever need the admin level going from Extranet to User is debatable.
> However I'm a bit stumped as to how you'd actually represent an association class in code. I mean I presume it'd need properties to represent the User, the Extranet and the Admin level but how do I actually use all three objects together to achieve my goal - listing the extranets available to a user with the admin level alongside?

Here i'd point out you need not think in terms of "foreign keys" or such, as that's not pertinent to OO. The fact that an object holds a collection of some sub-objects is in itself enough to implement a relationship. So, btw, you just implement the path from Users to Extranets if that's all you need.

Below is a simple starting structure (showing attributes only):

class User {
User_DBKey ABC // Key reference to user's data, maybe private
User_Attr XYZ // Some user's attribute

UserXExtranet_Collection UserXExtranets // UserXExtranet collection
}

class UserXExtranet {
UserXExtranet_Attr IsAdmin // UserXExtranet's IsAdmin attribute

Extranet_Ref Extranet // Extranet object reference
}

class Extranet {
Extranet_DBKey DEF // Key reference to extranet's data, maybe private
Extranet_Attr UVW // Some extranet's attribute
}

Hope this gives some basic ideas. Then you should further investigate concepts as "lazy loading" for a robust implementation. Also, please keep in mind i'm more of an analyst than a designer, so there might be better concrete ways than what i'm showing above...

HTH. -LV

0 comments:

Post a Comment