views:

133

answers:

7

I have a Person class which contains information like:

  • personId;
  • firstName;
  • lastName;
  • birthDate;
  • identityCardNumber;
  • address (contained Address object);
  • ... a lot more data about the person.

Whenever I need to perform operations on a person’s data, an object from this class provides all the info I need.

Now, I also have a page where a list of persona data is displayed. The list contains basic information about a person, allowing a user to select a row from the list and see detailed info about that person.

Because I do not want to return full Person objects from the database (could be for example 100 persons, but the user will just look at the details of a few) I am using another object for the list elements. This object is an instance of PersonData, which contains data such as:

  • personId;
  • firstName;
  • lastName;
  • ... some more data also found on Person, but on a much much smaller scale.

Because these classes share the same information and basically represent the same data, to avoid code duplication I was thinking of making PersonData the super class of Person. But, Person IS A PersonData does not sound right.

The question is, should I inherit from PersonData for the Person class or should I keep both separate? I could return incomplete Person objects for the list, instead of PersonData objects, but I don’t like that either.

How can I remove the code duplication but also have a clean design in the end, something intuitive and easy to maintain?

How would you tackle such a situation?

+1  A: 

Unless you have a concrete requirement for Person and PersonData to have a common supertype I would say there is no need, the types of the two classes can (and perhaps should) remain disconnected. Yes they are related but no need to over-complicate things. Just ensure you have a single place where you can translate between Person and PersonData.

Joe
I would add the in this case PersonData is a kind of view on person (as in SQL) the person HAS PersonData (embedded)
RA
What exactly does it mean: have a single place where you can translate between Person and PersonData? Can you please detail?
dpb
I mean a class that can take a Person and construct a PersonData or vice versa.
Joe
+5  A: 

A real Person has a personal identifier that is composed of id and the persons full name. So I'd choose composition (Person has PersonData).

Andreas_D
This keeps a clear separation, especially if there is any kind of serializing of the PersonData class, since it prevents anyone from trying to pass Person as a PersonData in any method calls. Not as important in a single VM case, but can make a huge difference if returning results via a network. The PersonData class is a simple value object with no functionality.
Robin
+2  A: 
  • Don't call it PersonData, come up with a better name.
  • Its also good to have two different tables, the idea is of master/detail where there would be one-to-one relationship. Then you can just query Person table to get the basic information, and fire another query against PersonaDetail in case user wants to see the details.
  • Now you can come up with two POJOs, Person and PersonDetail. And make the PersonDetail an attribute to Person. So, it would be composition, not inheritance.

Moreover, this kinda design will help you if you wanna use JPA or something.

Adeel Ansari
This exacty what we have where I work. All persons have a Person record, in addition all employees have a PersonDetail record.
Ken Lange
+1  A: 

"person is a PersonData" doesn't sound right, but only because of the nouns you've chosen. "AllPersonData is a PersonDataHolder" makes perfect sense, and represents the same logic. When testing is-a versus has-a, consider intent as well as the name. You could also rename the classes to make things clearer.

In brief, what you have is good to me:)

Binary Worrier
+1  A: 

Inheritance is not a IS A relation, more a BEHAVES LIKE. So Person can become an interface which is implemented by PersonData. Your repository can select only the data needed to fulfill the Person contract for the overview page.

Arne Burmeister
A: 

By implementing your Person class with a containing a object of the class PersonData I think it will be easy to understand and easy readable. Instead of using inheritance you will instead use composition (has a - relationship) which will work very good for you in your example.

If you decide to implement a IS A relationship through inheritance you have to consider all the pits and fallacies that comes through inheritance.

ChrisAD
A: 

Some of the information you're attributing to a Person isn't really about the person.

For example, though we might ask someone "what's your address?" in truth the address belongs not to the person, but to the house the person lives in. What if one of your Persons has a winter home and a summer home?

Likewise, the identityCardNumber probably relates not to the person, but to some kind of relationship the person has with some company.

kem
The identityCardNumber is the person's ID card, like your driver's license. It's your driver's license; it doesn't mean you have a relationship with the licensing bureau. The Address object sits on the Person, because on the PERSON table I have an ADDRESS_ID FK which points to the person’s address. I need that very often in using a Person, so it makes more sense to retrieve them both. Yes, it belongs to the house where I live in, but as a Person I do have an address, unless I’m homeless or something. But you didn’t answer the question; how would you handle the Person–PersonData relationship?
dpb
mm...no, I don't suppose I did...i thought you were asking a modeling question for some reason. It sounds like Person and PersonData both fit the Data Transfer Object pattern, then, in which case I favor making them completely independent objects. I think, in this case, that trying to relate them would probably achieve minimal code reuse at the expense of clarity.
kem