Coding to interfaces?

Viewed 11852

I want to solidify my understanding of the "coding to interface" concept. As I understand it, one creates interfaces to delineate expected functionality, and then implements these "contracts" in concrete classes. To use the interface one can simply call the methods on an instance of the concrete class.

The obvious benefit is knowing of the functionality provided by the concrete class, irrespective of its specific implementation.

Based on the above:

  1. Are there any fallacies in my understanding of "coding to interfaces"?
  2. Are there any benefits of coding to interfaces that I missed?

Thanks.

8 Answers

Just one possible correction:

To use the interface one can simply call the methods on an instance of the concrete class.

One would call the methods on a reference of the type interface, which happens to use the concrete class as implementation:

List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");

If you decided to switch to another List implementation, the client code works without change:

List<String> l = new LinkedList<String>();

This is especially useful for hiding implementation details, auto generating proxies, etc.

You'll find that frameworks like and encourage programming to an interface. It's the basis for ideas like programming, auto generated proxies for transaction management, etc.

Your understanding seems to be right on. Your co-worker just swung by your desk and has all the latest pics of the christmas party starring your drunk boss loaded onto his thumbdrive. Your co-worker and you do not think twice about how this thumbdrive works, to you its a black box but you know it works because of the USB interface.

It doesn't matter whether it's a SanDisk or a Titanium (not even sure that is a brand), size / color don't matter either. In fact, the only thing that matters is that it is not broken (readable) and that it plugs into USB.

Your USB thumbdrive abides by a contract, it is essentially an interface. One can assume it fulfills some very basic duties:

  1. Plugs into USB
  2. Abides by the contract method CopyDataTo:

    public Interface IUSB { void CopyDataTo(string somePath); //used to copy data from the thumbnail drive to... }

  3. Abides by the contract method CopyDataFrom:

    public Interface IUSB { void CopyDataFrom(); //used to copy data from your PC to the thumbnail drive }

Ok maybe not those methods but the IUSB interface is just a contract that the thumbnail drive vendors have to abide by to ensure functionality across various platforms / vendors. So SanDisk makes their thumbdrive by the interface:

public class SanDiskUSB : IUSB
 {
  //todo: define methods of the interface here
 }

Ari, I think you already have a solid understanding (from what it sounds like) about how interfaces work.

The main advantage is that the use of an interface loosely couples a class with it's dependencies. You can then change a class, or implement a new concrete interface implementation without ever having to change the classes which depend on it.

To use the interface one can simply call the methods on an instance of the concrete class.

Typically you would have a variable typed to the interface type, thus allowing only access to the methods defined in the interface.

The obvious benefit is knowing of the functionality provided by the concrete class, irrespective of its specific implementation.

Sort of. Most importantly, it allows you to write APIs that take parameters with interface types. Users of the API can then pass in their own classes (which implement those interfaces) and you code will work on those classes even though they didn't exist yet when it was written (such as java.util.Arrays.sort() being able to sort anything that implements Comparable or comes with a suitable Comparator).

From a design perspective, interfaces allow/enforce a clear separation between API contracts and implementation details.

The aim of coding against interfaces is to decouple your code from the concrete implementation in use. That is, your code will not make assumptions about the concrete type, only the interface. Consequently, the concrete implementation can be exchanged without needing to adjust your code.

You didn't list the part about how you get an implementation of the interface, which is important. If you explicitly instantiate the implementing class with a constructor then your code is tied to that implementation. You can use a factory to get an instance for you but then you're as tied to the factory as you were before to the implementing class. Your third alternative is to use dependency injection, which is having a factory plug the implementing object into the object that uses it, in which case you escape having the class that uses the object being tied to the implementing class or to a factory.

I think you may have hinted at this, but I believe one of the biggest benefits of coding to an interface is that you are breaking dependency on concrete implementation. You can achieve loose coupling and make it easier to switch out specific implementations without changing much code. If you are just learning, I would take a look at various design patterns and how they solve problems by coding to interfaces. Reading the book Head First: Design Patterns really helped things click for me.

As I understand it, one creates interfaces to delineate expected functionality, and then implements these "contracts" in concrete classes.

The only sort of mutation i see in your thinking is this - You're going to call out expected contracts, not expected functionality. The functionality is implemented in the concrete classes. The interface only states that you will be able to call something that implements the interface with the expected method signatures. Functionality is hidden from the calling object.

This will allow you to stretch your thinking into polymorphism as follows.

SoundMaker sm = new Duck();<br/>
SoundMaker sm1 = new ThunderousCloud();

sm.makeSound(); // quack, calls all sorts of stuff like larynx, etc.<br/>
sm1.makeSound(); // BOOM!, completely different operations here...
Related