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?
-
4Next time, please put some effort into making your question actually readable. I had to do a lot of reformatting.MetaFight– MetaFight2016年03月23日 14:59:26 +00:00Commented Mar 23, 2016 at 14:59
-
7Classes don't have foreign keys. You are assuming classes represent tables in a relational database and that's wrong.Tulains Córdova– Tulains Córdova2016年03月23日 15:02:51 +00:00Commented Mar 23, 2016 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– COME FROM2016年03月23日 15:09:40 +00:00Commented Mar 23, 2016 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– Rajeev2016年03月23日 15:17:59 +00:00Commented Mar 23, 2016 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– COME FROM2016年03月23日 15:23:35 +00:00Commented Mar 23, 2016 at 15:23
3 Answers 3
First a couple of observations:
- 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.
- How exactly do you tell what "defines the state" of an object and what doesn't? Perhaps for a
Person
class theBankAccount
is not part of its inner state but for an Employee class it does. dept_id
andaddress_id
don't follow any widely accepted Java naming convention, they should be nameddeptId
,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.
-
Thank you for the elaborate answer, now I think I should have the types Bank, Address and Department in my Employee class.Rajeev– Rajeev2016年03月23日 15:38:06 +00:00Commented Mar 23, 2016 at 15:38
-
2@RajeeVVenkaT Not the types, but members of that type.Tulains Córdova– Tulains Córdova2016年03月23日 15:39:54 +00:00Commented Mar 23, 2016 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– COME FROM2016年03月23日 15:44:11 +00:00Commented Mar 23, 2016 at 15:44
-
@COMEFROM I agree, and I will add it to my question with your permission.Tulains Córdova– Tulains Córdova2016年03月23日 15:45:11 +00:00Commented Mar 23, 2016 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– Greg Burghardt2016年03月23日 20:52:16 +00:00Commented Mar 23, 2016 at 20:52
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."
-
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– Jon Raynor2016年03月23日 17:14:21 +00:00Commented Mar 23, 2016 at 17:14
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).