Take a User class and the idea that a User is to be profiled. I see four ways to handle this:

Write the code for the profile into the User class. I am dismissing this right away.

Create a Profile class and make it a property of the User class.

Write a User class (with the boiler-plate name, address stuff), write a Profile class,
and write a UserProfile class - UserProfile is the union of User and Profile.

Write a User class and a Profile class that each have an ID property and let the ID act
as the intersection. This way the User and Profile are independent and another class,
possibly an abstract class with nothing but static methods handles the logic that
describes the connection.

Choices 3 and 4 each require at least three classes. For this case, which is the best choice? If possible to generalize this, would it generally be better to use one of these possibilities?

When you say "a User is to be profiled", what does that mean? What does your Profile class model?
–
BernardFeb 14 '12 at 20:25

1

Could you describe the user and profile in some details?
–
Emmad KareemFeb 14 '12 at 20:32

Bernard - the User is a user of the system and the profile, while in this case is meant to capture information about the financial position of the user, could be the data your doctor has that keeps him from giving you a prescription for something that you are alergic to. It would be most useful to capture ther more abstract case of such a profile than the specifics of a financial protfolio - or so it seems to me. The doctor and the financial advisor both need your personal data (profile) to have the best chance to do the right thing.
–
yasFeb 14 '12 at 20:41

1

"which is the best choice?" Define "best" in some measurable way. They all work. What are you trying to optimize? In tools like the Django web framework, your option 2 comes closest to the way it works. In that framework, best is defined by the framework. What are your criteria for "best"?
–
S.LottFeb 14 '12 at 20:55

1

@yas: You can't "generalize" this. There's no "general" answer, since it varies from framework to framework and it varies based on what needs to be optimized. There can never be a generalized "best" answer to questions like this. There are too many degrees of freedom and too many things which can be optimized.
–
S.LottFeb 14 '12 at 21:33

4 Answers
4

This is an easy decision. The user has a "has a" relationship to the profile and thus the profile should be encapsulated in its own class and exposed as a component of the User class (e.g. a property). So your second approach is the cleanest one.

Option 1 violates the single responsibility principle. This is only an option if there's very few data collected in profiles and almost not behaviour at all.

Option 2 is the way to go.

Option 3 is too complex. Also violates the single responsibility principle.

Option 4 just sounds like a horrible design. It'll be error prone and not really object oriented. Why would you want to intersect them via ID? That is built on a side effect entirely (namely matching ID of profile and user). You'll need some sort of reference from user to profile anyway. So why not have that reference in a property and let an ORM map it (see Option 2)?

It would be most useful to capture ther more abstract case of such a
profile than the specifics of a financial protfolio - or so it seems
to me. The doctor and the financial advisor both need your personal
data (profile) to have the best chance to do the right thing.

You can always extend from a Profile-BaseClass and store it in the User-Aggregate. And if you don't want to be implementation dependent, create a basic interface for everything that you need from the all cases of profiles that you can imagine.

thumbs up - quick, clear, and easy; this is what i need to know. Option 2 it is, thanks!
–
yasFeb 14 '12 at 20:46

2

option 1 doesn't necessarily violate the SRP, it only does if the user is something more than a profile. Given the question its hard to say for sure either way.
–
RyathalFeb 14 '12 at 20:47

1

@Tyathal: Yeah, that's right. But I assume that a profile contains data which does not necessarily fit in the user class. It's also good to keep such a class around for extensibility purposes.
–
FalconFeb 14 '12 at 20:54

Falcon, you mention extensibilty and that made me think about the reason I thought of option 3 and 4 though it was not extinsiblity but privacy. The ability to send or store the profile without the explicit connection to the user. Unfortunately, I don't really have set of requirements at this point; I only have the general idea. I'm just thinking through it in advance.
–
yasFeb 14 '12 at 21:05

@yas: Sure you can process (i.e. send, store) the profile separated from the user with Option 2. But a user must have a reference to one.
–
FalconFeb 14 '12 at 21:12

While it would seem like option 2 would be the sensible answer, it all depends on the context. Objects are not mainly for keeping data, but for modeling behavior. This means that to answer the question properly we need to know a lot more about what behavior the system should support. For instance it might be that the Profile is actually the most important concept in this system, and that the user should be hanging off of it. Or maybe there shouldn't even be a Profile class (or a User class), but some other classes based on what actions the user is to perform.

3.Write a User class (with the boiler-plate name, address stuff), write a Profile class, and write a UserProfile class - UserProfile is the union of User and Profile.

This is not a good option because User and UserProfile,Profile and UserProfile are tightly coupled.tight coupling is not a good design.

4.Write a User class and a Profile class that each have an ID property and let the ID act as the intersection. This way the User and Profile are independent and another class, possibly an abstract class with nothing but static methods handles the logic that describes the connection.