Interface vs. Implementation Dependencies in Java

I often use the notion of interface and implementation dependencies, where interface dependencies are mostly always smaller. I think this is a very important concept to understand for Java developers, and although it seems obvious and self evident, many developers do not think along those lines and still couple classes too tightly.

Take this example:

class CassandraStorage {
	public void store(String key, String value) {
	    otherPartOfApp.doSomething();
	    yetAnotherPart.doSomethingElse();
	    cassandraClient.store(key,value);
	}
}

class MyApp {
	@Inject CassandraStorage storage = null;
	public void myCode() {
			...
	}
}

The dependency chain for MyApp is:

MyApp -> CassandraStorage -> Cassandra Framework -> Many many more
                          -> Many other parts of application

The problem with this are the many dependencies the implementation of the Storage class introduces. When we add an interface, decoupling the usage from the implementation, we can decrease the numbers of dependencies significantly.

interface Storage {
	void store(String key, String value);
}

class MyApp {
	@Inject Storage storage = null;
	public void myCode() {
			...
	}
}

The dependency chain now only includes

MyApp -> Storage

broken away from

CassandraStorage -> Storage

with some benefits:

  • This breaks dependency chains early
  • Speeds up compilation
  • Easier to modularize
  • Helps break cycles

So use the concept of interface and implementation dependencies, where interface dependencies are mostly always smaller. I think this is a very important concept to understand for Java developers, and although it seems obvious, many do not think along those lines.