When does an object truly belong to a class? I’m familiar with the “has-a” relationship, but in the case of an Employee object, it “has-a” 401k, but it’s not really composed of a 401k object. As an employee, my 401k does not make me who I am.
What I’m getting at is, I don’t feel that I should need to reach into the Employee object to get to his 401k. Adherence to this would be considered adherence to the Law of Demeter (e.g. A().B().C().D()), which I would like to follow.
Additionally, an Employee object has a lot of attributes like an EmployeeID, age, dateOfBirth, etc. You could end up with infinite attributes just for an Employee, which all fall under the same responsibility.
In the case of a 401K, he doesn’t manage the 401k itself so the Employee still adheres to the Single Responsibility Principle, but he does “have” one. You just need to reach through the Employee object to get to his 401k. Even a Supervisor doesn’t really compose an Employee. Similar to a 401k, maybe the EmployeeRepository should have a FindSupervisor(Employee employee) method.
Is this where a repository & service comes in?
class Employee { public Employee(401k 401k) {...} public 401K Get401K() { return 401k; // EWW! No, does not follow LoD } public Money Calculate401k() { return 401k.calculate(); // Ugly and breaks SRP? No Employee should calculate 401k just to follow LoD... } private 401K 401k; } class 401K { public void MakeContribution(IContribution contribution) { //add contribution } public Money Calculate(ICalculator calculator) { //calculate & return money object } }
VS
class Employee { public int Age() {//calculate age with dob...} // Other employee-specific methods private string name; private DateTime dob; // other employee-specific attributes } class 401kRespository { public 401K FindByEmployee(Employee emp) {// return 401k of Employee); // More 401KRepo functions... } class 401K { public void MakeContribution(IContribution contribution) {//add contribution} public Money Calculate(ICalculator calculator) {//calculate} }