简体   繁体   中英

What is a good way to implement composition in Java?

The following classes display the concept of Composition in Java:

//Imagine constructors, accessors & mutators has already been created..

class Person{
    private String name;
    private Job job;    //Person has Job
}

class Job{
    private String name;
    private double salary;
}

My question is: If I want to get the salary from Person, which of the following 2 options is a better practice?

1. Get job of person, then get salary from job of person

System.out.println( person.getJob().getSalary() );

OR

2. Create a getSalary method in person, so I can do this:

System.out.println(person.getSalary());

Create a method to get salary from job first.

class Person{
    private String name;
    private Job job;
    public static double getSalary(){    //Is doing this redundant and bad practice?
        job.getSalary();
    }
}

Method 2 is a little bit better than method 1 because the code that gets the salary from a person is not dependent on any kind of Person->Salary relation implementation. You are free to change the way the salary is computed. In real life you can ask somebody what is is salary without knowing anything about his job. In your code, a liar can even returns an imaginary salary for him, etc.

To be honest I insist on the fact that method 1 cannot be considered as bad or false in any way, it has only small disadvantage in common situations...

Generally and personally I like method 1 because every redirection (how call this right?) make code a little bit more complicated. Imagine whole code has redirections for every relation. Even it's harder to communicate: 'do you mean Person.Salary or Person.Job.Salary?'.

But in your example I prefer method 2 because I can imagine extend Person to have multiple jobs or jobs beside pension or like.

There is a "Law" saying that option number 1 should be avoided, it's the Demeter's law aka principle of least knowledge

in particular

an object A can request a service (call a method) of an object instance B , but object A should not "reach through" object B to access yet another object, C , to request its services

HTH, Carlo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM