4

I know that an attribute defines the state of an object. So, is it correct to keep attributes that don't define the state of an object of a class?

For example, I have an Employee class, which has these attributes:

emp_id, fname, lname, mname, salary, mobile, email, gender, maritalstatus, position, birthdate, hiredate, dept_id, address_id, bank_id.

The dept_id, address_id and bank_id are foreign keys. Now my actual question is can we include attributes like bank_id, address_id and dept_id into Employee class because they are not actually showing exact behavior of Employee Class? Instead can I make another class named EmployeeForeignKeys and keep these attributes bank_id, address_id, dept_id in that class?

5
  • 4
    Next time, please put some effort into making your question actually readable. I had to do a lot of reformatting. – MetaFight Mar 23 '16 at 14:59
  • 7
    Classes don't have foreign keys. You are assuming classes represent tables in a relational database and that's wrong. – Tulains Córdova Mar 23 '16 at 15:02
  • What actual use do you have for these foreign key attributes? Do you need to show them to a user or deliver them to another application or system? – COME FROM Mar 23 '16 at 15:09
  • Actually, I have an Employee Table with foreign key attributes in database and I need to Insert records from Java. So, I have created an Employee class in java with attributes same as the columns of Employee Table. Later on I created object for Employee class ,set the parameters and sent the DTO object to the method which inserts records. – RajeeV VenkaT Mar 23 '16 at 15:17
  • Ok. I think Robert already provided a simple answer to your question. However, I think it's very questionable whether it's a good idea to have all or any of those foreign keys in your Employee class at all. You can always pick the bank_id from the Employee row when fetching the data of a Bank of an Employee for instance. That way you'll always get the right data, even when the employee has just changed bank. – COME FROM Mar 23 '16 at 15:23
7

First a couple of observations:

  1. Classes don't have foreign keys. You are assuming classes represent tables in a relational database and that's wrong. Not every class in the world will be persisted to a RDBMS, nor every RDBMS table will have a class modeled after it. That is wrong to begin with.
  2. How exactly do you tell what "defines the state" of an object and what doesn't? Perhaps for a Person class the BankAccount is not part of its inner state but for an Employee class it does.
  3. dept_id and address_id don't follow any widely accepted Java naming convention, they should be named deptId, addressID, etc.

An Employee class shouldn't have a bankID member but a bankAccount member which is of type BankAccount.

I wouldn't do this:

public class Employee{
    private int coBank;
    public int getCoBank(){};
}

but this

public class Employee{
    private BankAccount bankAccount;
    public BankAccount getBankAccount(){};
}

In the case of a person perhaps the banking information is not part of the class itself, so, you invert the logic so the person doesn't have a reference to the banking information and let the BankAccount have a reference to the person:

public class BankAccount{
    public Person owner getOwner(){};
}

In the case of en amployee, everyone should have a bank account to work properly so it makes sense the bank account to be part of its state.

In the case of a mere person that may not be so, so the bank account should reference the person and not the other way around.

EDIT:

@COMEFROM in one comment added some valid exceptions to my point on whether or not classes should have referencing IDs as members:

I think it's worth to mention that having referencing ID:s as attributes is alright in a larger scale, if the referenced entity is out of the scope of the system under design or if it otherwise belongs to some other context than the parent object.

6
  • Thank you for the elaborate answer, now I think I should have the types Bank, Address and Department in my Employee class. – RajeeV VenkaT Mar 23 '16 at 15:38
  • 2
    @RajeeVVenkaT Not the types, but members of that type. – Tulains Córdova Mar 23 '16 at 15:39
  • 2
    +1 I think it's worth to mention that having referencing ID:s as attributes is alright in a larger scale, if the referenced entity is out of the scope of the system under design or if it otherwise belongs to some other context than the parent object. – COME FROM Mar 23 '16 at 15:44
  • @COMEFROM I agree, and I will add it to my question with your permission. – Tulains Córdova Mar 23 '16 at 15:45
  • This looks good, except I don't see the benefit of using an interface here. Employee should just be a class. – Greg Burghardt Mar 23 '16 at 20:52
2

No, they go in the same class.

Try not to get too hung up on words definitions. An "attribute" (what the rest of the world calls a "field") is just a private member variable of the class, and that's all it is. The ID's are considered part of the state of the object, just like any other field.

When you're deciding if things should go together in a class, just consider whether or not they belong together conceptually. Don't hinge your decision on the finer points of some word definition like "state."

1
  • The Ids could have private setters. One could have a constructor that accepts them and sets them. This could be done in the data access layer. When you new up an object, these are set to zero indicating fresh relationships. These would differentiate other 'attributes' that provide public getters and setters like fname. – Jon Raynor Mar 23 '16 at 17:14
1

Ok, I think @Robert's answer goes directly to your question.

Further, the refactoring you suggest introducing another relation, EmployeeForeignKeys, having all the foreign keys together in one object/row doesn't help.

However, I sense you recognize some potential design issue in that perhaps too many responsibilities are being held by the employee class.

You've got quite a few 1-1 relationships: mobile, bank, email, position, address. Are you sure each employee has exactly one of these of interest to your business? This needs to be to considered by the business or domain stakeholder(s) and agreed upon as a business requirement, rather than just as an issue for the programmer(s) to resolve.

What can happen is that over time, you add home phone, 2nd email, 2nd address, then 3rd phone, 2nd position, etc.. You may find your users having to adding one employee twice in order to capture an additional phone or address or position. These kinds of relationships are sometimes better modeled using many-to-many relations (in tables) or lists (using classes).

My answer is that I wouldn't put these things as individual attributes in the employee class. For some of these, I would instead let other relations reference the employee (or maybe use lists).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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