3

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

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

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

  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.

  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.

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?

7
  • 5
    When you say "a User is to be profiled", what does that mean? What does your Profile class model?
    – Bernard
    Commented Feb 14, 2012 at 20:25
  • 2
    Could you describe the user and profile in some details?
    – NoChance
    Commented Feb 14, 2012 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.
    – yas
    Commented Feb 14, 2012 at 20:41
  • 2
    "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.Lott
    Commented Feb 14, 2012 at 20:55
  • 2
    @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.Lott
    Commented Feb 14, 2012 at 21:33

4 Answers 4

7

I'll assume that you are only storing profiles for users.

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.

5
  • thumbs up - quick, clear, and easy; this is what i need to know. Option 2 it is, thanks!
    – yas
    Commented Feb 14, 2012 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.
    – Ryathal
    Commented Feb 14, 2012 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.
    – Falcon
    Commented Feb 14, 2012 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.
    – yas
    Commented Feb 14, 2012 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.
    – Falcon
    Commented Feb 14, 2012 at 21:12
4

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

Why? This is the simplest solution. I would do this until the pain appeared. That moment may come very soon. So what if it does? Just extract the profile data into a separate class.

1
  • Exactly "profile" is just a fancy way of saying "users details". Commented Feb 15, 2012 at 6:03
0

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.

So the answer is: There is not answer!

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

It voilates Single Responsibility principle .Every class should provide only single responsibility.

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

It seems best option for two reasons.

1.satisfies Single responsibility Principle.

2.these two classes are loosly coupled.

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.

this is very complex,I strongly feel this complexity is not required.

finally you might want to read Headfirst Object Oriented analysis and design

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.