Question:
This question arose because of a … discussion with a colleague about what is preferable. There is code that can be written in two ways:
Method 1:
public interface MyInterface<T> {
T function(T prm);
}
and
Method 2:
public interface MyInterface {
<T> T function(T prm);
}
Implementation of the interface is one class MyInterfaceImpl (also with Generic for a class or method), the class is created using Spring DI
in class constructors, that is:
Method 1:
public class OtherClass {
private final MyInterface<String> str;
@Inject
public OtherClass(MyInterface<String> str) {
this.str = str;
}
Method 2:
public class OtherClass {
private final MyInterface str;
@Inject
public OtherClass(MyInterface str) {
this.str = str;
}
In principle, implementation in both ways is not a problem in itself. The question is the correctness, pros and cons of each approach. If you can, please provide quotes from Oracle documentation or well-known authors on the subject (I haven't found any good ones yet).
Update : Once again about the conditions: 1. interfaces and classes have only one method, 2. in each class where it is used, the interface / method works with only one type, 3. in principle, you can use both options.
Answer:
And so, and so right, you have to look at what is the point of your class. That is, you must program your classes so that their design matches the domain .
For example, if you have a universal factory for the production of weapons, then you have one, and the types of weapons can produce many:
public class WeaponFactory {
public <T extends Weapon> T produce() { ... }
}
And if you have a machine that produces one type of weapon, then this type is a "parameter" of the machine itself, and its type of weapon is predetermined:
public class WeaponMachine<T extends Weapon> {
public T make() { ... }
}
Look at the semantics of your classes.
I have no supporting sources, but I think this is one of the central, usually not spoken out loud principles of OOP.
We have many options to split responsibility between different methods and method groups. Some of them lead to problems. (For example, responsibility for some action may be mistaken for none of the objects.)
So, the idea is as follows: if you write objects and delegate authority in such a way that it corresponds to the skills and actions of objects in real life (that is, in the subject area ), then there are less chances for problems. Because this scheme works in real life? This means that it should work in the program. And if something doesn't work out, we can compare our code with a "working model" from reality, and see what piece of information we are missing.