Program to an interface, not an implementation

Posted

The term “interface” is somewhat generic, so the first time I heard it; I was pretty clueless about what it meant. It wasn’t until I got really serious about OOP and Design Patterns that I started to figure out what it was all about.

You might think that if you use the keyword Interface in C#, then you are following the principle. The problem with this is that when GoF published the Bible on Design Patterns, they didn’t mean for it to be that easy, because it is a bit more conceptual than that.

So what does “Program to an interface” really mean?

This principle is really about dependency relationships which have to be carefully managed in a large app. – Erich Gamma

To put it in other words, you have to follow the OO concept of Encapsulation; the exposed part of a class is its interface. The important part here is that the interface represents “what” the class can do but not “how” it will do it, which is the actual implementation.

Let us look at an example where we are programming to an implementation.

PepperoniPizza myPizza = new PepperoniPizza();
myPizza.Eat(); // returns "mmm, pepperoni"

The problem with this is that the interface is tightly coupled with the implementation, to decouple it we would have to abstract the interface of PepperoniPizza. This can easily be done through a tool like Resharper that has refactoring support. To make an abstraction of the interface, you could either make an Interface or an abstract class.

“Program to an interface”, really means “Program to a supertype”.
Head First, Design Patterns

public interface IPizza
{
	string Eat();
}

public class PepperoniPizza : IPizza
{
	public string Eat()
	{
		return "mmm, pepperoni";
	}
}

public static void Main()
{
	// programming to an interface
	IPizza myPizza = new PepperoniPizza();
	myPizza.Eat(); // outputs "mmm, pepperoni"
}

We know it is a PepperoniPizza, but we can use the IPizza reference polymorphically, which means that we can reuse it. We could easily replace the instantiation of the PepperoniPizza with another type of pizza that implements the IPizza Interface. There are different opinions about the I-naming convention for Interfaces, I’m not religious about it, but I like the idea of using it.

The next step would of course be to replace the hard-coded instantiation of PepperoniPizza with some sort of a method.

Interface vs. Abstract class

Choosing between these two really depends on what you want to do, but luckily for us, Erich Gamma can help us a bit.

As always there is a trade-off, an interface gives you freedom with regard to the base class, an abstract class gives you the freedom to add new methods later. – Erich Gamma

You can’t go and change an Interface without having to change a lot of other things in your code, so the only way to avoid this would be to create a whole new Interface, which might not always be a good thing.

Abstract classes should primarily be used for objects that are closely related, whereas interfaces are better at providing common functionality for unrelated classes.

If you know that the subclasses will share some common implementation, then you should use an abstract class, because Interfaces doesn’t have any implementation of its members.

Interface vs. API

Once you have given out your code and you no longer have access to all the clients, then you’re in the API business. – Erich Gamma

The difference between an interface and API can be summed up pretty quickly with the above statement. Clients can mean a few things. It can be another group inside the company or it can be a customer. Once the API has been published, then you have to support it and make sure it doesn’t break.

A Final word

When you are implementing an interface or inheriting from an abstract class then you could say that you have a contract with the object. This of course means that the object will always follow the rules of one or the other. This type of contract will for example help us when we are using Dependency Injection or want to create a Mock object.

Thank you for your help Tobias :)

Further reading

An interview with Erich Gamma

A java guy talks about Interface vs. Interface

Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley Professional Computing Series)

Head First Design Patterns

FacebookTwitterLinkedInGoogle+RedditbufferEmail

9 thoughts on “Program to an interface, not an implementation

  1. zproxy wrote:

    In a way the whole BCL is an interface. Atleast for my jsc project. There you are able to code against your rather usual desktop .net API and the code will be recompiled to a language your likeing. The actual implementation for the BCL depends on the target language.

    Hence the Base Class Library is by itself an interface for my multi platform projects.

    Do you agree?

  2. Mark Jensen wrote:

    I wouldn’t say that BCL is an interface; it is more of library then anything else because it consists of so many different things.

    :)

    /Mark

  3. Pingback: Reflective Perspective - Chris Alcock » The Morning Brew #352

  4. Dave wrote:

    Since C# does not allow multiple inheritence, Interfaces help developer add functionality to a class that conforms to a contract.

  5. Pingback: Ressources sur les principes avancés de conception objet

  6. Pingback: Méthodes avancées de dévelopement logiciel (entre autres)

  7. Nice article. It often takes developers some time to grasp the concept of interfaces. I remember I understood the concept at uni, but had a hard time seeing real beneficial usage. In my experience, projects where an IoC container is used helps the understanding and works great as an example of the power of interfaces. Interfaces helps managing dependencies as you say, and adding an IoC container helps you even more.

  8. Error454 wrote:

    Thank you for this article, it really cleared up my understanding of this famous phrase from the GoF book.

  9. Pingback: Interface in AS3 | Program to an interface, not an implementation // Shoguniphicus

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current day month ye@r *