331

Isn't the whole point of an interface that multiple classes adhere to a set of rules and implementations?

Lamin Sanneh
  • 4,025
  • 25
    see http://programmers.stackexchange.com/questions/150045/what-is-the-point-of-having-every-service-class-have-an-interface – k3b Aug 07 '12 at 07:53
  • 19
    Or to make it easier to unittest. –  Aug 07 '12 at 13:41
  • 11
    Allowing multiple classes to implement Interfaces and having your code depend on the interfaces is ESSENTIAL to isolation for unit testing. If you are doing unit testing, you will have another class implementing that interface. – StuperUser Aug 07 '12 at 14:10
  • The whole point of interfaces is to allow compile-time validation of method calls, preventing occurrences of 'Method not found' exceptions (as long as the run-time environment matches the compile-time environment). – kevin cline Aug 07 '12 at 16:49
  • This why I love dynamically bound languages - Unless you're checking isinstance(), all you care about is that whatever came in has the function/method/property you want to look at. Of course that makes good testing a priority... but requiring good practice isn't exactly a criticism... – Wayne Werner Aug 08 '12 at 11:12
  • 2
  • 9
    Public fields and methods are an "interface" in their own right. If the lack of polymorphism is intentionally planned then there is no reason to use an interface. The unit testing others mentioned is a planned use of polymorphism. – mike30 Dec 13 '12 at 19:04
  • How about the only class implementing that interface does more than just implement that particular interface and you don't want the code needing only the methods of said interface to have access to the rest of the public methods of the class. For eaxmple classes that implement both "immutable" and "mutable" behavior and you want most of your code to have an extra "insulation" layer between them and the methods that change an instance's state (insulation provided by having to "ask" whether the "mutable" interface is supported) so it is easy to spot the code that messes with state. – Marjan Venema May 09 '15 at 18:27
  • Found a perfect use case for an interface implemented by a single class just now, in this thread: http://programmers.stackexchange.com/questions/281979/is-my-usage-of-explicit-casting-operator-reasonable-or-a-bad-hack – Marjan Venema May 09 '15 at 19:19

16 Answers16

244

Strictly speaking, no you don't, YAGNI applies. That said, the time you'll spend creating the interface is minimal, especially if you have a handy code generation tool doing most of the job for you. If you are uncertain on whether you are going to need the interface of or not, I'd say it's better to err on the side of towards supporting the definition of an interface.

Furthermore, using an interface even for a single class will provide you with another mock implementation for unit tests, one that's not on production. Avner Shahar-Kashtan's answer expands on this point.

yannis
  • 39,597
  • 97
    +1 testing means you almost always have two implementations anyway – jk. Aug 07 '12 at 08:16
  • How does an interface apply to YAGNI? The linked wikipedia entry (to me) errs towards supporting the definition of an interface, rather than against it? – Deco Aug 07 '12 at 08:22
  • @Deco YAGNI == Don't build something you ain't going to need. If you are absolutely certain you don't have any use for the contract, why design by it? But of course, if you are not certain, then it's better to err towards supporting the definition of an interface, all you will have wasted is a little bit of time. – yannis Aug 07 '12 at 08:26
  • 36
    @YannisRizos Disagree with your latter point because of Yagni. Cranking an interface from a classes public methods is trivial after the fact, as is replacing CFoo with IFoo in consuming classes. There's no point in writing it in advance of the need. – Dan Is Fiddling By Firelight Aug 07 '12 at 12:26
  • @DanNeely that's assuming you have Resharper. – MattDavey Aug 07 '12 at 13:23
  • 3
    @MattDavey Even without Resharper (or its equivalent in other languages) it should only take a minute or two even on large classes. Deleting out anything private and the bodies of public methods isn't a difficult process. – Dan Is Fiddling By Firelight Aug 07 '12 at 13:30
  • @DanNeely I've updated the answer. – yannis Aug 07 '12 at 15:38
  • 7
    I'm still not sure I'm following your reasoning. Since code generation tools make adding it after the fact even cheaper, I see even less of a reason to create the interface before you have an explicit need for it. – Dan Is Fiddling By Firelight Aug 07 '12 at 17:11
  • 2
    @dan Not every language has handy code generation tools and not every developer likes using code generation tools even if they are available to them. – yannis Aug 07 '12 at 17:13
  • 8
    I think a missing Interface is not a good example for YAGNI but for a "broken Window" and missing Documentation. The users of the class are practically forced to code against the implementation, instead of the abstraction as they should. – Fabio Fracassi Aug 08 '12 at 09:02
  • 1
    @YannisRizos, even if they don't, I think I'd agree with Fabio about the non-violation of YAGNI. My personal opinion about developing in a statically bound language is that if you create a class, it probably needs an interface. The only exception (I've seen) is if the behavior of the class is actually part of another, interface'd class' API (e.g. a UserControl on a View). Then the tests against the interface should expose errors in the other class. – Wayne Werner Aug 08 '12 at 11:17
  • 5
    This assumes that every class should be mock tested, which is something that I would seriously question. – Konrad Rudolph Aug 08 '12 at 15:13
  • @KonradRudolph I'd love to read your answer, if you have the time to write one. – yannis Aug 08 '12 at 16:41
  • @YannisRizos I agree pretty much with your answer, but primarily the YAGNI aspect since, as I said, mocking isn’t always required. – Konrad Rudolph Aug 08 '12 at 18:07
  • 21
    Why would you ever pollute your codebase with meaningless cruft just to satisfy some testing framework? I mean seriously, I'm just a self-taught JavaScript client-side guy trying to sort out WTF is wrong with C# and Java developer OOD implementations I keep encountering in my pursuit of becoming more of a well-rounded generalist but why don't they slap the IDE out of your hands and not let you have it back until you learn how to write clean, legible code when they catch you doing that sort of thing in college? That's just obscene. – Erik Reppen Feb 12 '13 at 00:20
  • 3
    using an interface even for a single class will provide you with another mock implementation for unit tests, one that's not on production but mockito allow to create mock for a concrete class. So you shouldn't count it as a second implementation- thus no need for an interface? – user23621 Oct 23 '14 at 09:15
  • +1 for @DanNeely to post an answer to this question. I strongly endorse his perspective on the subject. – Julian A. Jul 31 '15 at 22:30
  • @Fabio Fracassi Coding against an interface doesn't mean against the special class named interface in java or C#. It means: code against the most abstract type in the inheritance hierarchy. For example, don't specify a Button parameter if Control fit the needs. Coding against IMyClass and MyClass is the same. MyClass has an implicit interface, as any class does. – Sylvain Rodrigue Jun 01 '20 at 10:10
197

I would answer that whether you need an interface or not does not depend on how many classes will implement it. Interfaces are a tool for defining contracts between multiple subsystems of your application; so what really matters is how your application is divided into subsystems. There should be interfaces as the front-end to encapsulated subsystems, no matter how many classes implement them.

Here's one very useful rule of thumb:

  • If you make class Foo refer directly to class BarImpl, you're strongly committing yourself to change Foo every time you change BarImpl. You're basically treating them as one unit of code that's split across two classes.
  • If you make Foo refer to the interface Bar, you're committing yourself instead to avoid changes to Foo when you change BarImpl.

If you define interfaces at the key points of your application, you give careful thought to the methods that they should support and which they should not, and you comment the interfaces clearly to describe how an implementation is supposed to behave (and how not), your application will be a lot easier to understand because these commented interfaces will provide a sort of specification of the application—a description of how it's intended to behave. This makes it much easier to read the code (instead of asking "what the heck is this code supposed to do" you can ask "how does this code do what it's supposed to do").

In addition to all of this (or actually because of it), interfaces promote separate compilation. Since interfaces are trivial to compile and have fewer dependencies than their implementations, it means that if you write class Foo to use an interface Bar, you can usually recompile BarImpl without needing to recompile Foo. In large applications this can save a lot of time.

sacundim
  • 4,786
  • 1
  • 20
  • 16
  • 25
    I would upvote this much more than once, if I could. IMO the best answer to this question. – Fabio Fracassi Aug 08 '12 at 09:05
  • 7
    If the class is only performing one role (ie would only have one interface defined for it), then why not do this via public/private methods? – Matthew Finlay Aug 08 '12 at 23:50
  • 6
  • Code organization; having the interface in its own file that has only signatures and documentation comments helps keep code clean. 2. Frameworks that force you to expose methods that you'd rather keep private (e.g., containers that inject dependencies through public setters). 3. Separate compilation, as mentioned already; if class Foo depends on interface Bar then BarImpl can be modified without having to recompile Foo. 4. Finer-grained access control than public/private offers (expose the same class to two clients through different interfaces).
  • – sacundim Aug 09 '12 at 00:56
  • 3
    And last one: 5. Clients (ideally) shouldn't care how many classes my module has or how many, or even be able to tell. All they should see is a set of types, and some factories or façades to get the ball rolling. I.e., I often see value in encapsulating even what classes your library consists of. – sacundim Aug 09 '12 at 01:01
  • +1 for separate compilation, which is sadly missing from the other answers. If class A uses class B directly, depending on language, A may need recompiling every time B is recompiled. Depend on an interface instead, and it only needs to be recompiled when the interface changes. See Bob Martin's original article on the Interface Segregation Principle for a detailed example in C++ (which is probably the worst language for this problem, but it exists in others too). – Jules Aug 01 '15 at 08:43
  • related to what is already written, but it's also great for keeping dirty dependencies out of layers you don't want them in. in you domain entities project, you probably want to be able to reference some kind of abstract repository for said entities. however, that doesn't mean you want a repository implementation in that project, because it will probably reference some DB vendor or some ORM and stuff like that. those things have nothing to do with the domain logic, and so they belong in another project focused on persistance. – sara Jul 19 '16 at 14:07
  • This makes it much easier to read the code (instead of asking "what the heck is this code supposed to do" you can ask "how does this code do what it's supposed to do"). Brilliant explanation – Alexander Derck Sep 08 '16 at 07:29
  • 21
    @sacundim If you make class Foo refer directly to class BarImpl, you're strongly committing yourself to change Foo every time you change BarImpl On changing BarImpl, what are the changes that can be avoided in Foo by using interface Bar? Since as long as signatures & functionality of a method doesn't change in BarImpl, Foo won't require change even without interface (the whole purpose of interface). I'm talking about the scenario where only one class i.e. BarImpl implements Bar. For multi class scenario, I understand Dependency Inversion Principle and how it interface is helpful. – Shishir Gupta Jun 18 '18 at 18:05
  • 3
    @ShishirGupta I was thinking the same. A good example there would be necessary to help to understand what he exactly means. – Anna Klein May 02 '19 at 19:48
  • 1
    @Shishir Gupta This is a common misunderstanding of interface. Many developpers doesn't know that every class has an implicite interface. Creating IMyClass and using it instead of MyClass add no isolation from (implicite) interface changes. – Sylvain Rodrigue Jun 01 '20 at 10:20