Do not start with an Interface

A few years back when I first started reading about design patterns, refactoring, OO principles etc. I got it into my head that I should “Always program to an interface not an implementation”. So whenever I needed to create a new class/abstraction I used to start of with an interface IThis, IThat etc. over a period of time I saw that most of my interfaces were only ever implemented by one class. This started becoming a pain to maintain as adding a new method meant that the method needed to be added to both the interface and the implementation class, further since there was only one implementation of the interface some developers started substituting one for the other and freely casting between the interface and the implementation. This became a source of constant code review changes and eyesores in code, with some methods expecting interfaces and others expecting the implementation class. Of course with strict code reviews we would never have got into this situation, but I’ve been working in startup companies all this time where getting something out there to earn $$$ has much higher priority than clean code.

Over the last few months I had to introduce some new features into our product which required that an abstraction that previously only had one implementation should now have 3, this was one of the cases where the class did not implement an interface. Contrary to what I had expected, refactoring the class and extracting an abstract class from it which was then subclassed by the different implementations lead to a very clean and satisfying design. This experience has taught me that unless you are writing code that interacts with something that is not under your control (a component or library for e.g.) it’s never a good idea to start with an interface.

On the other hand another feature that required extending an interface that was already defined became a big mess as a lot of the methods did not have a reasonable implementation under the new scheme and had to throw NotImplementedException’s. It was also difficult to refactor the interface as there were a huge number of dependencies. This could have been avoided if the Interface had been extracted on a need to need basis, further this would have lead to much more granular and cohesive set of interfaces rather than one huge bloated interface.

Starting with an interface on inward facing code means that you are making certain assumptions about how your code will evolve, in my experience these asumptions are almost always wrong and you end up supporting an interface that was never required in the first place. So now I start off with a concrete class and extract interfaces from the class as and when required, this has lead to much cleaner code and reduced the overhead of redundant definitions.

What have been your experiences in this matter?

15 Comments

 Add your comment
  1. Spot on. I am currently designing my class model and have experienced pretty much what you have jotted down here.
    Nice tip!

  2. I completely disagree with you that either OO principles or design patterns tells you to program to an interface.
    1. As per OO principals, interfaces are used mainly to exhibit polymorphism, which is basically, a single object behaving in multiple ways or all objects behaving in a similar way. The second one all objects behaving in multiple ways is of interest to us. This point implies that there are multiple implementations for the same functionality, and under this situation we use interfaces.
    2. In Design patterns, the patterns that uses interfaces, all have multiple implementation for the same functionality, like the strategy pattern.

  3. Ganesh thank you for sharing your experience.

    I think what the OO principles tell you depends a lot on the kind of literature you’ve read regarding the same, I am not saying that OO means that you should always program to an interface, what I am saying is that when I was starting out without having had the experience of developing and maintaining a large system this is what I understood regarding the principles, which I know now that I understood incorrectly. As usual with all things you need to be pragmatic rather than fanatic about following what you read. :)

    Also what I was trying to put across is that trying to anticipate what will be required in the future is a futile exercise, so if I am implementing an algorithm there is no need to start with a strategy interface unless I know that there are two or more implementations for the same. Again this only holds true for inward facing classes, for external classes this is obviously not true.

  4. Having most interfaces only implemented by one class is a clear sign that your code lacks integration and/or possibly even unit tests. As soon as you want to write serious tests, you will sooner or later have to mock some of your dependencies, and then, interfaces come in handy. When practicing test-driven development, you usually need interfaces almost right from the start.

  5. The problem is that you’re confusing implicit interfaces with explicit interfaces :).

    Much of the design patterns literature talks about programming to an interface. This stems from the the archetypal book on the subject: ‘The Design Patterns Elements of Reusable Object-Oriented Software’.

    The authors were very careful to define the term interface, referring to the [implicit] interface of an object or number of objects. Unfortunately it’s still interpreted as referring to the [explicit] interface construct as exhibited by languages like C# and Java.

    In this book was written by Smalltalk programmers and the examples appeared either in Smalltalk and or C++. Importantly, neither of these languages posses explicit interfaces.

    In Smalltalk, messages are sent to objects at runtime. Given a message an object chooses how to respond; it may choose to ignore the message. Desecrate objects can respond differently to a message. The end result is that programs are written against implicit interfaces. There’s no need to explicitly define the interface of your objects :).

    Note: In Objective-C the interface confusion doesn’t exist as explicit interfaces are called Protocols. This is a much better name for explicit interfaces. If you have the opportunity I’d recommend learning this language as it embodies a lot of the ideas from Smalltalk, in a natively compiled language.

  6. To clarify: programming to an implicit interface is advocated, not programming to an explicit interface. Thats not to say that explicit interfaces don’t have there uses :).

  7. Your experience with interfaces will vary depending on your mileage and problem solving approach. I have had good success with interfaces and generally start with interface design as opposed to concrete classes. Code integration is one of a group of parameters you need to consider in your adoption of interfaces. It is certainly NOT the only one.

    I have found interfaces to be and advantage while mocking unit test cases. Also while working with inversion of control (I use castle), interfaces provide a great deal of flexibility event when the code is internal and not expected to have multiple implementations.

    Refactoring tools included or added to you favorite tool allow the addition/modification of methods and properties to be relatively painless. The little extra effort pays up the flexibilities in unit testing, IOC and preliminary design.

  8. I find programming to an interface works quite well.

    However, if you find that your class is evolving beyond the original purpose, then it’s time to create a new class and/or interface (extending your previous if desired).

  9. +1 to Mark Smith’s comment.

    Another overloaded term causing confusion.

    It’s a good idea to have “Program to an interface, not an implementation” in the back of your head, but, as you state, that does not directly translate into creating an interface between every component of your system. When you talk about making changes in two places, your initial design was in violation of the open-closed principle. I think of the explicit interface of C++ or Java as an API.

    It’s all about managing dependencies between your code by thinking about polymorphism.
    The idea is that the interaction of your classes should be defined by an implicit interface, and when you are designing, you’re fitting those pieces together. When you go to code, it is then that you actually wire up, solder, plug in those interactions.

    Here’s what Erich Gamma (one of the GoF authors) says about it in an interview:

    Program to an interface, not an implementation

    Bill Venners: In the introduction of the GoF book, you mention two principles of reusable object-oriented design. The first principle is: “Program to an interface, not an implementation.” What’s that really mean, and why do it?

    Erich Gamma: This principle is really about dependency relationships which have to be carefully managed in a large app. It’s easy to add a dependency on a class. It’s almost too easy; just add an import statement and modern Java development tools like Eclipse even write this statement for you. Interestingly the inverse isn’t that easy and getting rid of an unwanted dependency can be real refactoring work or even worse, block you from reusing the code in another context. For this reason you have to develop with open eyes when it comes to introducing dependencies. This principle tells us that depending on an interface is often beneficial.

    You can find the rest of the interview here: http://www.artima.com/lejava/articles/designprinciples.html

  10. Also +1 to landlord – hiding details behind an interface allows you to fake that interaction out (using a mock or having a fake/stub stand in for the real component) which makes testing much easier.

  11. Use interfaces for the classes in your API where the implementation is likely to change or be extended or that may need to be proxied. Using an interface makes it possible to compose multiple implementation classes in a single class that implements those interfaces. Java proxies require an interface so if you think that a user may want to proxy your class then create an interface for it.

    If it is likely that only one implementation of a class is needed then skip the interface and create the class or maybe an abstract base class. When to create interfaces depends on how the API is going to be used and how long it is going to be in service and the likelihood that it will have multiple and concurrent implementations.

    For more info on creating useable API’s I recommend a talk given by Josh Bloch at Google. Search for “How To Design A Good API and Why it Matters”.

  12. I totally agree that interfaces are not usually required.

    The mantra “code to the interface” is so often misunderstood that it is dangerous. It is badly in need of being publicly branded as an anti-pattern.

    An example of this misunderstanding is ak’s comment above about requiring interfaces for mocking. Most Java mock object libraries support mocking of classes as well as interfaces (though you may need to enable this explicitly). This is due to the magic of libraries such as CGLIB.

  13. Programming to an interface need not allow your users to freely interchange interface and implementation types, if you hide the implementation type behind a factory method (potentially as an anonymous class).

    An interface can be annoying when you feel the urge to add static methods – sometimes I use abstract classes only for this reason.

    There may be parts of the contract that you cannot specify or check well enough in an interface that makes you rather use a concrete class. For example, the algebraic type Option with implementations Some and None – it is useful to be able to guarantee that Some and None are the only implementations.

  14. My experience has lead me away from inheritance. Largely because I have ended up with large unwieldy inheritance structures that needed to be modified and morphed. It sounds like you have ended up with the same situation but using interfaces. Maybe it is just a function of the sheer complexity of the programs we code?

    Inheritance always seemed easy in the OO books but in practice it can be a real pain. The same code using interfaces may also be just as much a pain in the long run. I have yet to run into any large unwieldy interface structures, but the more I use them the more I can see it happening.

  15. I do see a very strong point in what you have said. But it is quite opposite to one of the OO axioms: “design to interfaces”. It makes tough for someone thinking of starting to design a system :-). That is why it would require lot of experience to be able to foresee most the interfaces.

    IMO, one need to think of variability points of the system and decide to use interface or abstract class. Interface can easily make things more expandable, while abstract can be used to close the gates and hence a limiting factor.

Leave a Reply