38

Possible Duplicate:
What does it mean to “program to an interface”?

I keep coming across this term:

Program to an interface.

What exactly does it mean? A real life design scenario would be highly appreciated.

Community
  • 1
  • 1
gameover
  • 11,813
  • 16
  • 59
  • 70
  • 1
    another duplicate. i like this question really, but it has been posted many, many times... did you try to use search-bar? you get a lot of suggestions here: http://stackoverflow.com/search?q=programming+to+interface – manuel aldana Jan 03 '10 at 02:03

8 Answers8

82

To put it simply, instead of writing your classes in a way that says

I depend on this specific class to do my work

you write it in a way that says

I depend on any class that does this stuff to do my work.

The first example represents a class that depends on a specific concrete implementation to do its work. Inherently, that's not very flexible.

The second example represents a class written to an interface. It doesn't care what concrete object you use, it just cares that it implements certain behavior. This makes the class much more flexible, as it can be provided with any number of concrete implementations to do its work.

As an example, a particular class may need to perform some logging. If you write the class to depend on a TextFileLogger, the class is forever forced to write out its log records to a text file. If you want to change the behavior of the logging, you must change the class itself. The class is tightly coupled with its logger.

If, however, you write the class to depend on an ILogger interface, and then provide the class with a TextFileLogger, you will have accomplished the same thing, but with the added benefit of being much more flexible. You are able to provide any other type of ILogger at will, without changing the class itself. The class and its logger are now loosely coupled, and your class is much more flexible.

Eric King
  • 11,594
  • 5
  • 43
  • 53
  • Not a good answer, unfortunately. "Program *to* an interface" means *just* that. It does not mean that you can't depend on a specific class to do the work. As a counter-example to your `ILogger` example, I offer for consideration the classes `java.util.logging.Logger` and `org.apache.log4j.Logger`: both of these very popular logging APIs do *not* implement a separate interface, being used directly from client code. Client code which is still "programming to the interface", the interface of the `Logger` class. – Rogério Sep 19 '14 at 16:05
  • 2
    @Rogério The point isn't whether a particular Java class provides an explicit interface, but whether the code you write depends on the specific class instead of the interface it exposes. If you write code that depends specifically on `org.apache.log4j.Logger`, you _are not_ "programming to an interface". If you write code that doesn't care whether the logger provided is `java.util.logging.Logger` or `org.apache.log4j.Logger` or any other logger implementation that exposes the common interface, then you _are_ programming to an interface. – Eric King Sep 19 '14 at 17:10
  • @EricKing But people *do* write code to the interface of `Logger` classes all the time. When they do that, they *are* programming to the interface; for sure, they are not programming to any implementation *inside* the class. I think you are confused about what an "interface" is. The `java.util.logging.Logger` public class, like any other public class, has an *implicit* public interface, but an interface nonetheless, to which you can program to. – Rogério Sep 19 '14 at 18:04
  • @Rogério No, I know exactly what an interface is, implicit and explicit. We are agreeing that if the code you write only knows about and cares about and depends on the _interface_, then we're golden. 'Programming to implementation' does not mean 'depending on otherwise encapsulated internals of a class', which you seem to be implying. It's depending on _any specific class_ (e.g., creating a constructor that requires a 'java.util.logging.Logger' implementation, that won't work with a `org.apache.log4j.Logger') to do your work. – Eric King Sep 19 '14 at 18:59
  • @EricKing Ok, we agree on what an interface is. About the principle of "program to an interface, not an implementation" (from GoF), my interpretation is as explained in "Effective Java", 2ed., item 52 "Refer to objects by their interfaces". It is about the type you use for local variables, parameter types, and return types; it does not forbid instantiating an implementation class with `new`, nor does it mandate every class having a *separate* interface. From the book: "It is entirely appropriate to refer to an object by a class rather than an interface if no appropriate interface exists." – Rogério Sep 19 '14 at 19:17
  • @Rogério That's fine, but it's a bit more lenient than I'm comfortable with. If you have to modify your class in order to take advantage of a different dependent implementation, even if it exposes the same public interface, then you're not really programming to the interface, are you? In other words, if you write a class that news up a specific logger implementation, and you cannot substitute another logger implementation _with the same interface_ without altering your class' code, then you're not programming to an interface. If you can do so, then you are. – Eric King Sep 19 '14 at 19:35
  • @EricKing Yes, we can agree on that. The situation shouldn't come up where we need to change client code to use a different implementation of some component. But note that the `Logger` classes I used as examples do not have this problem; you wouldn't need to change client code to, for example, direct the logging output somewhere else. It's important to clarify the understanding of this principle, because in the real world it too often occurs that developers create lots (I seen projects with hundreds) of absolutely pointless and worthless separate interfaces. – Rogério Sep 19 '14 at 19:50
  • I like this explanation of what "programming to an interface" might mean: http://softwareengineering.stackexchange.com/a/232366. – Mihai Danila Feb 23 '17 at 15:03
20

An interface is a collection of related methods, that only contains the signatures of those methods - not the actual implementation.
If a class implements an interface (class Car implements IDrivable) it has to provide code for all signatures defined in the interface.

Basic example:
You have to classes Car and Bike. Both implement the interface IDrivable:

interface IDrivable 
{
    void accelerate();
    void brake();      
}

class Car implements IDrivable 
{
   void accelerate()
   { System.out.println("Vroom"); }

   void brake()
   { System.out.println("Queeeeek");}
}

class Bike implements IDrivable 
{
   void accelerate()
   { System.out.println("Rattle, Rattle, ..."); }

   void brake()
   { System.out.println("..."); }
}

Now let's assume you have a collection of objects, that are all "drivable" (their classes all implement IDrivable):

List<IDrivable> vehicleList = new ArrayList<IDrivable>();
list.add(new Car());
list.add(new Car());
list.add(new Bike());
list.add(new Car());
list.add(new Bike());
list.add(new Bike());

If you now want to loop over that collection, you can rely on the fact, that every object in that collection implements accelerate():

for(IDrivable vehicle: vehicleList) 
{
  vehicle.accelerate(); //this could be a bike or a car, or anything that implements IDrivable
}

By calling that interface method you are not programming to an implementation but to an interface - a contract that ensures that the call target implements a certain functionality.
The same behavior could be achieved using inheritance, but deriving from a common base class results in tight coupling which can be avoided using interfaces.

Thomas Zoechling
  • 34,177
  • 3
  • 81
  • 112
9

Polymorphism depends on programming to an interface, not an implementation.

There are two benefits to manipulating objects solely in terms of the interface defined by abstract classes:

  1. Clients remain unaware of the specific types of objects they use, as long as the objects adhere to the interface that clients expect.
  2. Clients remain unaware of the classes that implement these objects. Clients only know about the abstract class(es) defining the interface.

This so greatly reduces implementation dependencies between subsystems that it leads to this principle of programming to an interface.

See the Factory Method pattern for further reasoning of this design.

Source: "Design Patterns: Elements of Reusable Object-Oriented Software" by G.O.F.

Also See: Factory Pattern. When to use factory methods?

Community
  • 1
  • 1
Joe Phillips
  • 49,743
  • 32
  • 103
  • 159
8

Real-world examples are applenty. One of them:

For JDBC, you are using the interface java.sql.Connection. However, each JDBC driver provides its own implementation of Connection. You don't have to know anything about the particular implementation, because it conforms to the Connection interface.

Another one is from the java collections framework. There is a java.util.Collection interface, which defines size, add and remove methods (among many others). So you can use all types of collections interchangeably. Let's say you have the following:

public float calculateCoefficient(Collection collection) {
    return collection.size() * something / somethingElse;
}

And two other methods that invoke this one. One of the other methods uses a LinkedList because it's more efficient for it's purposes, and the other uses a TreeSet.

Because both LinkedList and TreeSet implement the Collection interface, you can use only one method to perform the coefficient calculation. No need to duplicate your code.

And here comes the "program to an interface" - you don't care how exactly is the size() method implemented, you know that it should return the size of the collection - i.e. you have programmed to the Collection interface, rather than to LinkedList and TreeSet in particular.

But my advice is to find a reading - perhaps a book ("Thinking in Java" for example) - where the concept is explained in details.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
4

Every object has an exposed interface. A collection has Add, Remove, At, etc. A socket may have Send, Receive, Close and so on.

Every object you can actually get a reference to has a concrete implementation of these interfaces.

Both of these things are obvious, however what is somewhat less obvious...

Your code shouldn't rely on the implementation details of an object, just its published interface.

If you take it to an extreme, you'd only code against Collection<T> and so on (rather than ArrayList<T>). More practically, just make sure you could swap in something conceptually identical without breaking your code.

To hammer out the Collection<T> example: you have a collection of something, you're actually using ArrayList<T> because why not. You should make sure you're code isn't going to break if, say, you end up using LinkedList<T> in the future.

Kevin Montrose
  • 22,191
  • 9
  • 88
  • 137
  • "Every object has an exposed interface" - um. No it doesn't? Those you listed do, but plenty don't implement any interfaces. – Nyerguds Jan 06 '17 at 14:12
3

"Programming to an interface" happens when you use libraries, other code you depend upon in your own code. Then, the way that other code represents itself to you, the method names, its parameters, return values etc make up the interface you have to program to. So it's about how you use third-party code.

It also means, you don't have to care about the internals of the code you depend on, as long as the interface stays the same, your code is safe (well, more or less...)

Technically there are finer details, like language concepts called "interfaces" in Java for example.

If you want to find out more, you could ask what "Implementing an Interface" means...

raoulsson
  • 14,978
  • 11
  • 44
  • 68
2

I think this is one of Erich Gamma's mantras. I can't find the first time he described it (before the GOF book), but you can see it discussed in an interview at: http://www.artima.com/lejava/articles/designprinciples.html

Uri
  • 88,451
  • 51
  • 221
  • 321
2

It basically means that the only part of the library which you're going to use you should rely upon is it's API (Application programming interface) and that you shouldn't base your application on the concrete implementation of the library.

eg. Supposed you have a library that gives you a stack. The class gives you a couple of methods. Let's say push, pop, isempty and top. You should write your application relying only on these. One way to violate this would be to peek inside and find out that the stack is implemented using an array of some kind so that if you pop from an empty stack, you'd get some kind of Index exception and to then catch this rather than to rely on the isempty method which the class provides. The former approach would fail if the library provider switched from using an array to using some kind of list while the latter would still work assuming that the provider kept his API still working.

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169