Back to Basics: What is an Interface?

This is the first part of my Back to Basics series.

One of the basics I feel we really need to get back to is the use and understanding of the value of interfaces.

In languages like C# and Java, interfaces are extremely common.  They are much more commonly used than they were 5-10 years ago.

But a question we have to ask ourselves is, “are we using them correctly?”

What problem does the interface solve?

I want you to take a second and clear your head of how you are currently using interfaces.

I want you to pretend for a moment that you don’t know what an interface is.

Ready?

The basic problem an interface is trying to solve is to separate how we use something from how it is implemented.

Why do we want to separate the use from the implementation?

So that we can write code that can work with a variety of different implementations of some set of responsibilities without having to specifically handle each implementation.

To put this more simply, this means that if we have a Driver class it should be able to have a method Drive that can be used to drive any car, boat, or other kind of class that implements the IDriveable interface.

The Driver class should not have to have a DriveBoat, DriveCar or DriveX methods for each kind of class that supports the same basic operations that are needed for it to be driven.

driver race car thumb Back to Basics: What is an Interface?

Interfaces are trying to solve a very specific problem by allowing us to interact with objects based on what they do, not how they do it.

Interfaces are contracts

Interfaces allow us to specify that a particular class meets certain expectations that other classes can rely on.

If we have a class that implements an interface, we can be sure that it will support all the methods that are defined in that interface.

At first glance interfaces seem to be similar to concrete inheritance, but there is a key difference.

Concrete inheritance says Car is an Automobile, while an interface says Car implements the Drivable interface.

When a class implements an interface, it does not mean that class IS that interface.  For this reason interfaces that completely describe the functionality of a class are usually wrong.

A class can implement multiple interfaces because each interface only talks about a particular contract that class is able to fulfill.

Interfaces are always implemented by more than one class

You might be saying “no they’re not, I have a class here that has an interface that no other class implements.”

To that I say, “you are doing it wrong.”

But, don’t worry, you are not alone.  I am doing it wrong also.  Many of us are not using interfaces correctly anymore, but are using them instead because we are under the impression that we should never use a concrete class directly.

We are afraid of tightly coupling our application, so instead we are creating interfaces for every class whether or not we need an interface.

There are some really good reasons why I say that interfaces are always implemented by more than one class.

Remember how we talked about how interfaces are designed to solve a particular problem?

In my example, I talked about how the Driver class shouldn’t have to have a method of each kind of class it can drive, instead it should depend on an IDriveable interface and have one generic Drive method that can drive anything that implements IDrivable.

Most of us accept the YAGNI principle which says “You Ain’t Gonna Need It.”  If we only have a Car class and we don’t have any other classes that need to be driven by the Driver class, we don’t need an interface.  YAGNI!

At some point we may later add a Boat class.  Only at that point in time do we actually have a problem that the interface will solve.  Up until that point adding the interface is anticipating a future problem to solve.

If you think you are good at anticipating when you will need an interface, I want you to do a little exercise.  Go into your codebase and count all the interfaces you have.  Then count all the classes that implement those interfaces.  I bet the ratio is pretty close to 1 to 1.

But how will I test?  How will I use dependency injection?

These two reasons are probably the most justified causes for incorrectly using interfaces.

I am guilty of justifying the creation of an interface so that I can have something to mock, and I am guilty of creating an interface just for my dependency injection framework, but it doesn’t make it right.

I can’t give you an easy answer here and say that I can solve your unit testing or dependency injection problems without an interface, but I can talk about why we shouldn’t be bending the source code to fit the tool or methodology.

I talked about the purpose of unit testing before, and one of the key benefits being that unit tests help guide your design.  Unit tests help us to decouple our application and consolidate our classes to single responsibilities by making it really painful to try and unit test classes with multiple dependencies.

Interfaces are kind of a shortcut that allows us to get rid of having lots of dependencies in a class.

When we turn a reference to a concrete class into an interface reference, we are cheating the system.  We are making it easier to write a unit test by pretending that our class is decoupled because it references an interface instead of a concrete class.  In reality it is not decoupled it is actually more coupled because our class is coupled to an interface which is coupled to a class.  All we did was add a level of indirection.

Dependency injection promotes the same problem of interface abuse.  At least it does in the way it is used in C# and Java today.  Creating an interface solely for the purpose of being able to inject the only implementation of that interface into a class creates an unnecessary level of indirection and needlessly slows down the performance of our application.

Don’t get me wrong.  Dependency injection is good.  I’ll save the details for another post, but I believe dependency injection’s real benefit is when it is used to control which implementation of an interface is used, not when there is only one implementation of an interface.

Ultimately, I can’t give you a good answer of how do you unit test or use dependency injection without abusing interfaces.  I think you can reduce the abuse by choosing to split apart classes and actually reduce dependencies rather than simply creating an interface and injecting it into the class, but you are still going to have the problem that a Car has an Engine and if you want to unit test the car, you are either going to have to use the real engine or find a way to mock it.

The key problem here is that interfaces are part of the language, but unit testing and dependency injection are not.  We are trying to make them fit in with the language by using a trick.  The trick is we create an interface to provide a seam between classes.  The problem is that we dilute the potency of an interface by doing so.  What we really need is a language supported seam to allow us to easily replace implementations of concrete classes at runtime.

  • http://invalidcast.com Martin

    “What we really need is a language supported seam to allow us to easily replace implementations of concrete classes at runtime.”

    I completely agree and I’ve been realising this recently too. During the PDC talk, I was secretly hoping that Anders would hint about something in C# 5 which allowed this in some way. It’s almost like we need a way to infer an implicit interface without having to specify it.

    Microsoft’s Moles goes some way in solving the problem, but isn’t nearly as clean as if we had a language feature for this stuff. In case anyone is interested, I wrote about using Moles in this way here http://invalidcast.com/2010/03/moles-dig-it

    • http://simpleprogrammer.com jsonmez

      Replied on your post. But, I’ll reply here also. Thank you!
      I am going to have to look more at moles, but that seems to be exactly the kind of thing that can solve this problem.
      There is a place for mocking and dependency injection, but the place is not everywhere.

  • http://www.newitup.com/ Dan

    Using interfaces for testing doesn’t really break the rules in my mind. Whether you’re manually creating stubbed classes for testing or having a mocking framework generate a proxy class from your interface, they are both technically a 2nd (or more) implementation of your interface which is OK by your rule: “Interfaces are always implemented by more than one class”. Granted – they’re specialized implementations for the purposes of unit testing, but I think it still applies that you’re using the interface to separate usage from implementation. In the tests, we want some form of expected, dummy form of implementation so we stub or mock an interface to get that implementation.

    • http://simpleprogrammer.com jsonmez

      The problem with this line of thinking is that, we can rationalize creating an interface for any reason (since we can make a 2nd implementation by mocking it in a test.)
      Also, what happens here is we end up making our production code more complicated and less cohesive, so that we can unit test. The unit testing should be improving our design.
      The problem is that coupling and cohesion are inversely related to some degree. When we start creating interfaces for everything, we decouple our system, but at the cost of cohesion.

      • Chris Rogers

        Actually, I think Dan is correct. Take for instance, some business logic which may need to send an email notification.
        You will probably never need any more than one concrete implementation of an email sending service – but you certainly do NOT want unit tests to hit a real SMTP server. Similar story for data layers – where you often really do need to mock up data situations.

        Your basic premise is still hard to disagree with … but it is very easy to think of real situations like the above, where mocked implementations serve a very real, valid need.

        • http://simpleprogrammer.com jsonmez

          Agreed, you do not want to hit the real SMTP server or the real data layer for something like a unit test, but at the same time we don’t want to make a bad design decision for the purpose of creating a unit test.
          Right now there is a gap here which forces us to choose to use interfaces too often.
          Check out that link on mole for a possible solution. Ultimately though, I don’t have a great answer. I do hope to find one.
          Perhaps we can do some kind of compile time substitution for a class?

  • configurator

    I did your exercise on two projects. In one I had 0 interfaces, and in the other I had 1 interface – and 32 implementing classes.

    I’m not sure if those results are good or bad though.

    • http://simpleprogrammer.com jsonmez

      Yeah, it is debatable. But I think good. It is better to not use any interfaces than to abuse them perhaps. And definitely in the 2nd project if you only have 1 interface and you are using it that much, that means it is really needed.

      Out of curiosity, do either of those projects have unit tests or use dependency injection?

      • configurator

        The one without any interface is really small and is very well-covered by unit tests, made easy by the stupidly simple interfaces (no pun intended). I’m very happy about code quality in this one.

        The one with a single interface has plenty of tests but they’re not what you’d call unit test – the setup method usually imports files from a known location into a database, then we test the entire thing against live databases, then drop it in the teardown method.

  • Duncan

    It’s not appropriate to have an interface for an entire class, because the entire class prolly won’t be used in a test — it’s just a short-hand we’ve fallen into because our tools permit us to extract an interface from an entire class without thinking. But even with DI, you’re not likely going to use the entire class facade.

    Where we might have been tempted to pass in an IBoat mock, we would never use the .FuelCapacity property in the same test as the .TipToStern property, so why are they in the same interface? Why not IFuelSystem and IDimensions interfaces?

    It’s been staring us all in the face and we didn’t see it. So glad you pointed this out!

  • Pingback: Tweets that mention Back to Basics: What is an Interface? « Making the Complex Simple -- Topsy.com()

  • http://igorbrejc.net Igor Brejc

    Looks like the guys that implemented ASP.NET MVC followed your logic and they didn’t provide interfaces like IHttpContext (since they probably considered only one implementation is needed for their framework).

    In the end it turned out to be a lousy decision, since now you cannot really reuse parts of the ASP.NET MVC code (routing is one example) without dragging around the whole framework.

    Which brings me to a question: how can you know in advance how many implementations of an interface there will be in the future? Your logic of interfaces being even more coupled than concrete classes is simply wrong.

    As you said yourself, an interface is a _contract_, so you’re only coupled to a contract, which anyone can implement. On the other hand, directly binding to a concrete class means you’re coupled to a concrete _implementation_.

    • http://simpleprogrammer.com jsonmez

      You bring up a good point. I think the good answer here is that it depends on if you are publically publishing an API or not. In the ASP.NET MVC case, perhaps they should have used an interface, because it was public facing and people would be wanting to extend or reuse it.

      But, in your internal applications, you have a different set of considerations. In code that is not exposed to the world, we shouldn’t be thinking ahead.

  • Moutasem Alawa

    I think you’ve got a point here, and i am starting to be fan of duck-typing and dynamic languages. Because every time we see added complexity to applying new software trends such as SOLID principles i think its caused by less-intelligent (strongly types) languages.
    At certain points interfaces are good, as you mentioned there main reason so for an IDriveable or IAbstractBehavoiur it’s good useful and used properly.

  • Bjørn Erik Haug

    I sometimes make every public method virtual instead of adding an interface when there will only be a single implementation. That way I can still mock it. This is useful to provide a seam between classes that are part of the same “bundle”, like Car and CarDoor where the CarDoor isn’t likely to be reused and an interface seems like too much.

    I wish C# allowed me to specify virtual on the class level just like static so I’m less prone to add a new non-virtual and have the real thing get called in tests.

    • http://simpleprogrammer.com jsonmez

      I agree with you there. In Java methods are virtual by default unless they are marked as final, which seems like a good choice to me. I’m not a big fan of concrete inheritance, but it is better to use it to mock a class in a unit test than to abuse an interface IMO.

  • Pingback: Back to Basics: Cohesion and Coupling Part 2 « Making the Complex Simple()

  • http://www.relentlessdevelopment.net Grant C

    Very interesting – although I must say I’m kind of torn now! Agree with the abuse of interfaces, and I’ve been getting quite uncomfortable with some of the code I’ve been writing lately which is mainly there for testability (although it’s miles better than the code I was writing before I started unit testing!).

    However, it seems to be generally agreed that newing up things inside the calling class is bad, regardless of language features or testing. Is the answer, as you and Bjorn have alluded to, to use DI with concrete classes instead of interfaces, and to make everything in that concrete class virtual so it can still be mocked? Even with that approach, making everything virtual for testing isn’t something everyone would be happy with.

    Or do we continue with DI, forget about the current limitations of the language and use Moles/TypeMock for all our testing? Which sounds ok, but completely removes the need for good (or at least, better) design which ‘traditional’ unit testing forces you into, and will probably mean a number of people never even find out what DI (and all the other good stuff) is because they don’t need to use it to make their tests work.

    **** it, I’m going to go and join the Rubyists…

    • http://simpleprogrammer.com jsonmez

      Good questions, no easy answers here. I am more and more getting the feeling that the answer will lie in moving away from unit testing and focusing more on either integration level testing or automated functional testing from the UI. Either that or a new language that doesn’t have a “new” keyword.
      One question I have to ask myself is if we are using languages where we have the “new” keyword, but we say it is bad to use… are we trying to solve problems with the wrong tools?

      • Suhas Chatekar

        Are you serious about moving away from unit testing? Unit testing are most useful because quick feedback loop. Integration/Acceptance tests do not give you quick and pin-pointed feedback. I would rather review every usage of interface and make sure interfaces are not abused instead of abandoning unit testing altogether.

        • jsonmez

          Yes, there is certainly still a place for unit testing, but much of the unit testing I see today with heavy dependency injection and mocking really doesn’t test much at all.

          • Suhas Chatekar

            Ruling our interfaces completely is equally wrong as ruling out unit testing or dependency injection for that matter. All three have their strengths and bad spots if used in a wrong way. They all need to be balanced to achieve SOLID. It is not very difficult to come up with example to support any argument in the world of programming.

  • Pingback: Back to Basics: Unit Testing, Automated Blackbox Testing, and Conclusions! « Making the Complex Simple()

  • Rahul Sahay

    Thanks for the post John. Thats really helpful in clearing the concepts @ granular level.

  • John Giannetti

    Great post. I see interface abuse quite extensively in C# code these days. You even see ridiculous interfaces for what are really glorified data structures (example: ICustomer). When interfaces are used correctly, I think they express behavior not data. And, they don’t really have many methods. IEnumerable has only one method in its signature and IEumerator has three. And some think that reset was a mistake! This shows that interfaces are extremely powerful when used correctly, but used incorrectly they mostly get in the way.

    I not am not real fan of unit testing since I develop data-base oriented applications. I just never seen a need there, but I have found integration testing to be useful. Apparently, typemock is a framework that allows you to test dependencies without using the standard dependency injection techniques. Here is a link that discusses this: http://www.infoq.com/news/2007/12/does-di-pay-off

    • jsonmez

      Thanks great comment. I agree about integration testing. Typemock is very nice, works like magic! :)

  • Stephen Byrne

    Very nice article, and although I agree with you in general, I’d be inclined to say that 1:1 interface=>implementation is not *necessarily* a sign of bad design…I take it to mean that in the following example:

    public class Car:IDrivable
    {
    public void Drive(){Console.WriteLine(“Vroom!Beep!”);};
    public decimal Fuel{get;set;}
    public void OpenBoot(); //and many other badly designed methods/properties, etc.
    }

    public interface IDrivable
    {
    void Drive();
    }

    ….all we’re doing here is using the language conttructs available to us in C# to declare to a consumer “look, the only thing I can guarantee about that IDrivable Car I gave you is that it has a Drive() method.” – i.e the “Contract” aspect of an interface.
    Now if there were some way to take your concrete implementation of Car and specify the contract inline on the actual class members , then that’d be just fine – but pointless unless you absolutely only ever needed a single concrete implementation of that behaviour, because otherwise you would need some way to share this definition of contract in a central place…bringing you right back to the interface keyword!

    Also I would disagree that using interfaces for Unit testing is in some way an artificial and unnatural thing – in fact it’s more natural to me if I have a class “GroceryShopper” and I want to test that it goes to the store and buys milk given a means of transport:
    Surely a properly isolated unit test says “Drive that IDrivable thing I gave you to the store and get some milk” because we really only care about the milk, not the vehicle, as opposed to “Drive this Car to the store…” where we are now relying on having a working and callable Drive method that won’t throw, etc…and even if you use a stub Car object, how do you guarantee that the stub’s Drive method won’t drift in signature from the concrete’s method without some kind of…contract…to enforce it, thus rendering your tests meaningless unless you test objects by contract only.

    Just my 2c :)

    • jsonmez

      Thanks for the comment, I do see your point and the way you suggest makes sense.
      I think it is a perfectly reasonable conclusion. We both can probably agree that interface abuse is bad and is prevalent today. Which is the real problem that must be tackled. Thanks for the insights.

      • Róbert Papp

        How about using Java’s Powermock/Easymock classextension (which is part of the core since v3)/or alike to mock a drive method on a Car, wich gives the same flexibility of having that indermediary interface just to restrict which method can be called.

        • jsonmez

          That would be work as well.