[language-agnostic] What does it mean to “program to an interface”?



14 Answers

The specific example I used to give to students is that they should write

List myList = new ArrayList(); // programming to the List interface

instead of

ArrayList myList = new ArrayList(); // this is bad

These look exactly the same in a short program, but if you go on to use myList 100 times in your program you can start to see a difference. The first declaration ensures that you only call methods on myList that are defined by the List interface (so no ArrayList specific methods). If you've programmed to the interface this way, later on you can decide that you really need

List myList = new TreeList();

and you only have to change your code in that one spot. You already know that the rest of your code doesn't do anything that will be broken by changing the implementation because you programmed to the interface.

The benefits are even more obvious (I think) when you're talking about method parameters and return values. Take this for example:

public ArrayList doSomething(HashMap map);

That method declaration ties you to two concrete implementations (ArrayList and HashMap). As soon as that method is called from other code, any changes to those types probably mean you're going to have to change the calling code as well. It would be better to program to the interfaces.

public List doSomething(Map map);

Now it doesn't matter what kind of List you return, or what kind of Map is passed in as a parameter. Changes that you make inside the doSomething method won't force you to change the calling code.

Question

I have seen this mentioned a few times and I am not clear on what it means. When and why would you do this?

I know what interfaces do, but the fact I am not clear on this makes me think I am missing out on using them correctly.

Is it just so if you were to do:

IInterface classRef = new ObjectWhatever()

You could use any class that implements IInterface? When would you need to do that? The only thing I can think of is if you have a method and you are unsure of what object will be passed expect for it implementing IInterface. I cannot think how often you would need to do that... (Also, how could you write a method that takes in an object that implements an interface? Is that possible?)

Sorry if I completely missed the point.




Imagine you have a product called 'Zebra' that can be extended by plugins. It finds the plugins by searching for DLLs in some directory. It loads all those DLLs and uses reflection to find any classes that implement IZebraPlugin, and then calls the methods of that interface to communicate with the plugins.

This makes it completely independent of any specific plugin class - it doesn't care what the classes are. It only cares that they fulfill the interface specification.

Interfaces are a way of defining points of extensibility like this. Code that talks to an interface is more loosely coupled - in fact it is not coupled at all to any other specific code. It can inter-operate with plugins written years later by people who have never met the original developer.

You could instead use a base class with virtual functions - all plugins would be derived from the base class. But this is much more limiting because a class can only have one base class, whereas it can implement any number of interfaces.




In Java these concrete classes all implement the CharSequence interface:

CharBuffer, String, StringBuffer, StringBuilder

These concrete classes do not have a common parent class other than Object, so there is nothing that relates them, other than the fact they each have something to do with arrays of characters, representing such, or manipulating such. For instance, the characters of String cannot be changed once a String object is instantiated, whereas the characters of StringBuffer or StringBuilder can be edited.

Yet each one of these classes is capable of suitably implementing the CharSequence interface methods:

char charAt(int index)
int length()
CharSequence subSequence(int start, int end)
String toString()

In some cases Java class library classes that used to accept String have been revised to now accept the CharSequence interface. So if you have an instance of StringBuilder, instead of extracting a String object (which means instantiating a new object instance), can instead just pass the StringBuilder itself as it implements the CharSequence interface.

The Appendable interface that some classes implement has much the same kind of benefit for any situation where characters can be appended to an instance of the underlying concrete class object instance. All of these concrete classes implement the Appendable interface:

BufferedWriter, CharArrayWriter, CharBuffer, FileWriter, FilterWriter, LogStream, OutputStreamWriter, PipedWriter, PrintStream, PrintWriter, StringBuffer, StringBuilder, StringWriter, Writer




It sounds like you understand how interfaces work but are unsure of when to use them and what advantages they offer. Here are a few examples of when an interface would make sense:

// if I want to add search capabilities to my application and support multiple search
// engines such as google, yahoo, live, etc.

interface ISearchProvider
{
    string Search(string keywords);
}

then I could create GoogleSearchProvider, YahooSearchProvider, LiveSearchProvider etc.

// if I want to support multiple downloads using different protocols
// HTTP, HTTPS, FTP, FTPS, etc.
interface IUrlDownload
{
    void Download(string url)
}

// how about an image loader for different kinds of images JPG, GIF, PNG, etc.
interface IImageLoader
{
    Bitmap LoadImage(string filename)
}

then create JpegImageLoader, GifImageLoader, PngImageLoader, etc.

Most add-ins and plugin sytems work off interfaces.

Another popular use is for the Repository pattern. Say I want to load a list of zip codes from different sources

interface IZipCodeRepository
{
    IList<ZipCode> GetZipCodes(string state);
}

then I could create an XMLZipCodeRepository, SQLZipCodeRepository, CSVZipCodeRepository, etc. For my web applications I often create XML repositories early on so I can get something up and running prior to the Sql Database being ready. Once the database is ready I write an SQLRepository to replace the XML version. The rest of my code remains unchanged since it runs soley off of interfaces.

Methods can accept interfaces such as:

PrintZipCodes(IZipCodeRepository zipCodeRepository, string state)
{
    foreach (ZipCode zipCode in zipCodeRepository.GetZipCodes(state))
    {
        Console.WriteLine(zipCode.ToString());
    }
}



short story:Postman is asked to go home by home and receive the covers contains (letters,documents,cheques,giftcard,application,loveletter) with address written on it to deliver.

Suppose there is no cover and ask post man to go home by home and receive all the things and deliver to other person the postman can get confuse,

so better wrap it with cover(in our story it is interface) then he will do his job fine.

Now postman job is to receive and deliver the covers only..(he dont bothered what is inside in the cover).

Create type of interface not actual type, but implement with actual type.

Create to interface means your components get Fits into the rest of code easily

I give you example.

you have AirPlane interface as below.

interface Airplane{
    parkPlane();
    servicePlane();
}

Suppose you have methods in your Controller class of Planes like

parkPlane(Airplane plane)

and

servicePlane(Airplane plane)

implemented in your program. It will not BREAK your code. I mean, it need not to change as long as it accepts arguments as AirPlane.

Because it will accept any Airplane despite of actual type, flyer, highflyr, fighter, etc.

Also, in a collection:

List<Airplane> plane; // Will take all your planes.

The following example will clear your understanding.


You have a fighter plane that implements it, so

public class Fighter implements Airplane {

    public void  parkPlane(){
        // Specific implementations for fighter plane to park
    }
    public void  servicePlane(){
        // Specific implementatoins for fighter plane to service.
    }
}

The same thing for HighFlyer and other clasess:

public class HighFlyer implements Airplane {

    public void  parkPlane(){
        // Specific implementations for HighFlyer plane to park
    }

    public void  servicePlane(){
        // specific implementatoins for HighFlyer plane to service.
    }
}

Now think your controller classes using AirPlane several times,

Suppose your Controller class is ControlPlane like below,

public Class ControlPlane{ 
 AirPlane plane;
 // so much method with AirPlane reference are used here...
}

here magic comes as

you may make your new AirPlane type instances as many as you want and you are not changing

code of ControlPlane class.

you can add instance..

JumboJetPlane // implementing AirPlane interface.
AirBus        // implementing AirPlane interface.

you may remove instances.. of previously created types too.




Using interfaces is a key factor in making your code easily testable in addition to removing unnecessary couplings between your classes. By creating an interface that defines the operations on your class, you allow classes that want to use that functionality the ability to use it without depending on your implementing class directly. If later on you decide to change and use a different implementation, you need only change the part of the code where the implementation is instantiated. The rest of the code need not change because it depends on the interface, not the implementing class.

This is very useful in creating unit tests. In the class under test you have it depend on the interface and inject an instance of the interface into the class (or a factory that allows it to build instances of the interface as needed) via the constructor or a property settor. The class uses the provided (or created) interface in its methods. When you go to write your tests, you can mock or fake the interface and provide an interface that responds with data configured in your unit test. You can do this because your class under test deals only with the interface, not your concrete implementation. Any class implementing the interface, including your mock or fake class, will do.

EDIT: Below is a link to an article where Erich Gamma discusses his quote, "Program to an interface, not an implementation."

http://www.artima.com/lejava/articles/designprinciples.html




Programming to an interface has absolutely nothing to do with abstract interfaces like we see in Java or .NET. It isn't even an OOP concept.

What it really means is don't go messing around with the internals of an object or data structure. Use the Abstract Program Interface, or API, to interact with your data. In Java or C# that means using public properties and methods instead of raw field access. For C that means using functions instead of raw pointers.

EDIT: And with databases it means using views and stored procedures instead of direct table access.




I am a late comer to this question, but I want to mention here that the line "Program to an interface, not an implementation" had some good discussion in the GoF (Gang of Four) Design Patterns book.

It stated, on p. 18:

Program to an interface, not an implementation

Don't declare variables to be instances of particular concrete classes. Instead, commit only to an interface defined by an abstract class. You will find this to be a common theme of the design patterns in this book.

and above that, it began with:

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.

So in other words, don't write it your classes so that it has a quack() method for ducks, and then a bark() method for dogs, because they are too specific for a particular implementation of a class (or subclass). Instead, write the method using names that are general enough to be used in the base class, such as giveSound() or move(), so that they can be used for ducks, dogs, or even cars, and then the client of your classes can just say .giveSound() rather than thinking about whether to use quack() or bark() or even determine the type before issuing the correct message to be sent to the object.




Also I see a lot of good and explanatory answers here, so I want to give my point of view here, including some extra information what I noticed when using this method.

Unit testing

For the last two years, I have written a hobby project and I did not write unit tests for it. After writing about 50K lines I found out it would be really necessary to write unit tests. I did not use interfaces (or very sparingly) ... and when I made my first unit test, I found out it was complicated. Why?

Because I had to make a lot of class instances, used for input as class variables and/or parameters. So the tests look more like integration tests (having to make a complete 'framework' of classes since all was tied together).

Fear of interfaces So I decided to use interfaces. My fear was that I had to implement all functionality everywhere (in all used classes) multiple times. In some way this is true, however, by using inheritance it can be reduced a lot.

Combination of interfaces and inheritance I found out the combination is very good to be used. I give a very simple example.

public interface IPricable
{
    int Price { get; }
}

public interface ICar : IPricable

public abstract class Article
{
    public int Price { get { return ... } }
}

public class Car : Article, ICar
{
    // Price does not need to be defined here
}

This way copying code is not necessary, while still having the benefit of using a car as interface (ICar).




Here is a simple example to illustrate when you program a flight booking system.

//This interface is very flexible and abstract
    addPassenger(Plane seat, Ticket ticket); 

//Boeing is implementation of Plane
    addPassenger(Boeing747 seat, EconomyTicket ticket); 
    addPassenger(Cessna, BusinessClass ticket);


    addPassenger(J15, E87687); 



Program to an interface allows to change implementation of contract defined by interface seamlessly. It allows loose coupling between contract and specific implementations.

IInterface classRef = new ObjectWhatever()

You could use any class that implements IInterface? When would you need to do that?

Have a look at this SE question for good example.

Why should the interface for a Java class be preferred?

does using an Interface hit performance?

if so how much?

Yes. It will have slight performance overhead in sub-seconds. But if your application has requirement to change the implementation of interface dynamically, don't worry about performance impact.

how can you avoid it without having to maintain two bits of code?

Don't try to avoid multiple implementations of interface if your application need them. In absence of tight coupling of interface with one specific implementation, you may have to deploy the patch to change one implementation to other implementation.

One good use case: Implementation of Strategy pattern:

Real World Example of the Strategy Pattern




It is also good for Unit Testing, you can inject your own classes (that meet the requirements of the interface) into a class that depends on it




In addition to the already selected answer (and the various informative posts here), I would highly recommend grabbing a copy of Head First Design Patterns. It is a very easy read and will answer your question directly, explain why it is important, and show you many programming patterns you can use to make use of that principle (and others).




If you program in Java, JDBC is a good example. JDBC defines a set of interfaces but says nothing about the implementation. Your applications can be written against this set of interfaces. In theory, you pick some JDBC driver and your application would just work. If you discover there's a faster or "better" or cheaper JDBC driver or for whatever reason, you can again in theory re-configure your property file, and without having to make any change in your application, your application would still work.




Interface is like contract where you want your implementation class to implement methods written in contract(Interface).Since java does not provide multiple inheritance,programming to interface is a good way to achieve purpose of multiple inheritance.If you have a class A that is already extending some other class B but you want that class A should also follow certain guidelines or implement certain contract then you can do so by programming to interface strategy.




Related