Apart from the obvious market-wise need for a companies to appear as a continuous sources of innovation (investors like that), there are some technical issues involved too. This post looks at how java8 can change some of the dependency issues; it may even change how you do java7 right now.
Java7
The dilemma: A class/library wishes to reuse external services, which introduces dependencies.
public class MyClass {
private ExternalDependency1 ed1;
private ExternalDependency1 ed2;
public int doSomething(String input){
return ed1.calculate( ed2.transform( input));
}
}
Now this is the classical reason why need to make *our* module depend on something external, ExternalDependency1 and ExternalDependency2 are defined in another project. This is basically the technical reason why we have 280 different "spring" projects; they all tie in with their different dependencies.
Java8 to the rescue
In java8, we can easily move the declaration of the required type *into* MyClass, which makes it self-contained with respect to dependencies:public class MyClass {
public interface InternalDependency1 {
int calculate(String source);
}
public interface InternalDependency2 {
String transform(String source);
}
private InternalDependency1 id1;
private InternalDependency2 id2;
public MyClass(InternalDependency1 id1, InternalDependency2 id2) {
this.id1 = id1;
this.id2 = id2;
}
public void doSomething(String input){
id1.calculate( id2.transform( input));
}
}
At first glance, this seems like just additionally bloating the code. We need to look at the use before it all becomes clear:
ExternalDependency1 ed1 = new SomeObject1();
ExternalDependency2 ed2 = new SomeObject1();
MyClass mc = new MyClass( ed1::calculate, ed2::transform);
Now this is where the subtle magic happens; any method that matches the *shape* of the calculate or transform method will be autoboxed into something that can be *used* as InternalDependency1/2.
With this one magic little change, MyClass suddenly lost all its external dependencies.
What about java.util.function.Function ?
Some of you will notice that I am using 1 method interfaces instead of the generic java.util.function.Function class. There are several reasons for this:
A) It is an explicit type that will some day provide IDE support. Current IDE support is somewhat sketchy, but this will improve.
B) "MyClass" is a library component that is expected to have clients; the "cost" of these interfaces making the external contract of "MyClass" 100% clear is probably worth it in the long run.
C) This is java5/6/7 compatible, although the java7 client will have a slightly less cool client api (anonymous inner class galore)
D) If you use Function, the only thing expressing the intention of the function will be the local variable name; in this case id1 and id2. This makes our java code all javascripty; much as I love javascript I am a little sceptical about too this in java; at least for "library" style code.