views:

12098

answers:

53

Ok, I may resort to a tad ranting here, so let me apologize in advance, but I'm really curious if others find this pattern annoying too (and I wonder if it is a justifiable pattern)…

So, after just looking at a particular question, I noticed that almost all of the responses suggested creating an interface for injecting a mock in some test code.

I don't mind using interfaces, and sometimes they can really help in static typed languages like C# and Java… but I do mind seeing interfaces for almost every class in a system (or in general being used where they aren't really needed).

I have 2 major problems with using an interface when it isn't called for:

  • You abstract away where the implementation is coming from. This problem has a couple consequences… in an IDE, it means that when I try to browse to the source of this method being called… I get taken to an interface instead of some code that I can look at and see what is going on. This bothers me a lot, but also this is a real problem to me to hide where the implementation is coming from (sometimes it can be in non-obvious locations).
  • It adds ANOTHER file to the system. I tend to be a minimalist in my programming… if I don't really need another method, or another class, or even another file… not unless that extra thing is justified (flexibility that is going to be used, or makes the design cleaner, or provides some real benefit).

Now… if you are testing something, and you create an interface JUST TO ALLOW MOCKING… this seems to be adding a layer of minor headaches for no real benefit. What does creating the interface do that just overriding the class won't do? What is so bad about having a mock that merely overrides some methods of the single implementation class?

I guess it should be no surprise then that I much prefer Java's default virtual methods (ie requiring a final keyword to have a method that CAN'T be overriden) to C#'s default final methods… and I also tend to avoid the final keyword on methods and classes too.

So is there something to using interfaces that I am missing? Is there some hidden benefit of using an interface when you have 1 version of a class and no immediate need to create an interface?

+22  A: 

I completelly AGREE WITH YOU!

I stated this in my ansewer: http://stackoverflow.com/questions/90657/mocking-method-results#90687

And I had to edit my answer twice to be clearer, because almost all answers suggested creating an interface to an UTILITY class. This kind of answer was even accepted. You should create an interface for testing purposes if it makes sense - which it does NOT in the context of the question.

Creating an interface is not even the biggest problem. I think the worst is obligate a client class to inject the interface implementation when calling a simple operation. This will increase the complexity all code using that class. This is very bad. It's a hack! A BAD hack! Why is it bad?

  • It's an Utility class. It's not likely to change implementation. So why even bother adding other layer of abstraction?!
  • Was suggested over and over to inject the Utility class implementation in classes that uses it. Now code that looks like this: myClass.loadData() will look like this: myClass.loadData(new HelperImplementation()). NO!!
  • +1 to all the points stated by Mike
  • There are other - more elegant - ways.
  • Must be other reasons why it's bad. :)
Marcio Aguiar
I like your response! When I need dependency injection, I tend to prefer to sneak it in via protected methods if I don't need to expose it to the client (it makes the tests more complicated, but the client code less complicated)
Mike Stone
I don't think you understand D.I. You would never call myClass.loadData(new HelperImplementation()), you would pass the reference when you instantiate it (likely in the class's c-tor).
Andrew
+2  A: 

You abstract away where the implementation is coming from. This problem has a couple consequences... in an IDE, it means that when I try to browse to the source of this method being called... I get taken to an interface instead of some code that I can look at and see what is going on. This bothers me a lot, but also this is a real problem to me to hide where the implementation is coming from (sometimes it can be in non-obvious locations)

This could be considered to be a problem with your IDE. For C# editing, I use Jetbrains ReSharper, and it has a natty "Go to Inheritor" feature that takes you from a method in the interface to the implementation. I suspect that other VS addons (Visual Assist, the DevX tools, etc.) will have a similar feature.

If you're on Eclipse (I'm not), I suspect that someone will have cooked up something similar.

Roger Lipscombe
That's a cool feature, but it seems to me almost like an ide workaround to an antipattern (if there is 1 implementation so the ide can do it... why is there an interface?)
Mike Stone
A: 

And the following is really good

Wikipedia:

One benefit of using interfaces is that they simulate multiple inheritance. All classes in Java (other than java.lang.Object, the root class of the Java type system) must have exactly one base class; multiple inheritance of classes is not allowed. However, a Java class/interface may implement/extend any number of interfaces.

And at least in Java EJB interfaces where used for defining home and remote interfaces. A very practical way of describing which functionality will be available from outside of your VM.

mana
You seem to be describing a legitimate use of interfaces... I'm more talking about using interfaces when multiple inheritance or multiple implementations is NOT NEEDED (which is more often than not).
Mike Stone
+4  A: 

By programming against interfaces you're able to switch to implementation in a central place, e.g. a factory, a builder or dependency injection, which is a good thing.

The downside is a higher complexity, so using interfaces depends on your requirements/needs. If you have a fixed implementation that yould never change, let it be.

GHad
The problem is, when you are done with your project and you have 50 interfaces with 1 implementation each, what did that added complexity gain you? I'm all for interfaces... but I say, bring them out when you see a pressing need for them.
Mike Stone
Damn I wish I could up vote your comment here mike.
grom
Me too. Sometimes I use an "agile" methodology : ONLY when I have two classes that share something in common I will create an interface for them.
Andrei Rinea
Switching implementation is essential if your project is large and you would like to be able to fix bugs or add functionality without having to recompile/reinstall/resetup the whole application, for every customer. I can fix a bug in a class, send out the containing dll by itself as an update, and let the factory use its own logic to decide to use the newer version, without ever having to touch the installation.
Joel in Gö
A: 

Interfaces allows you to work in a higher level of abstractation. that's important if you're planning on adding more use-cases (=classes)somewhere in the future.

Amir Arad
Why not extract the interface when you DO add those extra classes at that FUTURE point?
Mike Stone
absolutely right. I had very short-term planning in mind.
Amir Arad
Exactly... plus I don't get where this "higher level of abstraction" is achieved.... closures are a higher level of abstraction, not interfaces.
Mike Stone
higher level of abstraction is achieved when you can refer to the prototype rather than a specific implementation of it... no? did I get it wrong?
Amir Arad
+41  A: 

If you have one class I can understand your hesitation with interfaces. According to Robert Martin's book Agile Patterns and Practices (I believe that's the name of it). In the book he describes the Dependency Inversion Principle. I don't believe he invented it but he's who made it click for me.

Basically the more you depend on interfaces the less fragile your software. This is an ideal though. I say break it where it makes sense. If you're not using interfaces more often than you are then there may be other problems. For example, just because you have different classes doesn't mean they should all have different interfaces. The interface segregation principle states that we should break up interfaces into the most reuseable atomic components possible.

For example imagine having 100 different data access classes (each for a different kind of entity). They could have their own interfaces but what if they shared a common ICrud interface? Then you know each supports the basic CRUD methods. In this way you should be looking to add consistency and order through out your code... ideally. No one's perfect at it (and productive) but it's a good ideal to strive for.

Justin Bozonier
I think "depending on an interface" can be replaced with "depending on a class that can easily have it's entire implementation replaced in a subclass"... but I agree with a lot of what you are saying.
Mike Stone
Hehe, yeah I agree with you Mike. Really when I say interface I'm referring to the concept of what an interface is as opposed to the language feature. The same terminology applies to Javascript, Python, etc. IMO. Good point man.
Justin Bozonier
The Dependency Inversion Principle is great. A complex system is a fragile system. If using DI for a concept makes your system less complex then you should use it, if it makes it more complex then stay away.
Hallgrim
The 100 different data access classes sounds fairly insane in itself :)
alchemical
+8  A: 

(And to think I almost failed a Software Engineering exam because I had placed interfaces only on classes that required it, rather than everywhere...)

millenomi
LOL, sorry to hear it! Sounds like your professor (or whoever was grading it) is stuck in theory land...
Mike Stone
Yes that sounds like a very unfair test. You should not need to agree with the examiner on such a subjective issue to get points.
finnw
+7  A: 

You do not add the interface for allowing mocking. In reality, if you need to mock something, is because there is a dependency on an external component, and the interface is used to decoupling that dependence, which in return allows Mocking, but thats a consecuence of a better design, not a requirement for mocking.

The problem with the question you link is this:

I want to have a known result from the Helper.GetSomeData() method. Can I use a mocking framework (I've got fairly limited experience with Rhino Mocks but am open to anything) to force an expected result? If so, how?

The user needs a deterministic result, so the only solutions are mock the helper, or just hardcode the value directly.

On your concerns:

If you try to brownse the code for an interface's implementation in your project you didt't code, chances are that you probably know beforehand what the implementation is (maybe because of a previouse debug trace), or that you IDE have an 'find all references' for that interface, or better utilities if you use third party plugins (an user said in this question that Resharper has a "go to inheritor' option) I don't think is a big deal.

Adding a new file is good. Really. Separate all files and implementations in numerouses files is not a bad thing, because we have tools that take that bunch of files and organize it in a proper structured way: a project. Your real concern here is not adding a new file, but adding new simbols you need to care about ,IMHO, which add complexity to the project.

Ricky AH
But what is the difference between passing in an implementation and an interface? Both cases it is injected, both cases it can be mocked... I see no benefit of not passing the class itself (unless it is a legacy object that wasn't designed with testing in mind).
Mike Stone
That's what Dependency Injection is all about. If you use an interface you decouple the implementation, and then you can inject any object which follows that interface. If you pass a concrete implementation, you'll need to change the method signature in order to mock it, as they are different types.
Ricky AH
+16  A: 

I'm with ya, but have always kept quiet about it. It is one of those cases where people become obsessed with 'the rule' and lose pragmatism in their designs. (Like bureaucrats becoming obsessed with the bureaucracy rather then the purpose.)

A few years back I took over a project that had zillions of single class implementations of a corresponding interface...in a closed system (The API was never externally exposed.) WTF? Grrr.

Interfaces have their place, but it's not everywhere. :P

On a side note, I cannot stand interfaces prefixed with I (E.g.: IMyInterface). Can anyone say Hungarian Notation? (For the hair splitters, it is 'Systems Hungarian Notation', to be specific.)

Stu Thompson
YES YES YES! +1
Mike Stone
I like interfaces with the I in front of them.... as oposed to SomethingSomethingInterface. Less verbose
Mario Ortegón
I prefer "interface Munger {..}; class MungerImpl {...};". MungerImpl is usually a private inner class of MungerFactory or similar.
finnw
NO NO NO 0(zero).It's not really hungarian notation..
Andrei Rinea
Prefixing with I is always done in Microsoft's API's, and this pattern is followed across the industry when coding in C#. Plus, it's nice to immediately know the difference between List and IList. I don't like Hungarian notation in general , but I do like this convention.
Neil Whitaker
+72  A: 

A big headache with interfaces in Java and C# is that they give you so few options to evolve your contract. E.g.:

interface ILogSink {
  Log(DateTime timestamp, string message);
}

If you have a lot of different clients that all implement this interface you cannot change it without breaking their implementation. If you need to change it in the next version, you end up with something like:

interface ILogSinkVersion2 {
  Log(DateTime timestamp, string message, CultureInfo culture);
}

If you use a base class on the other hand, you can start out with:

class LogSink {
  void Log(DateTime timestamp, string message, CultureInfo culture);
}

And evolve it to:

class LogSink {
  [Obsolete("Please Log(DateTime, string, CultureInfo)")]
  virtual void Log(DateTime timestamp, string message) {
  }

  virtual void Log(DateTime timestamp, string message, CultureInfo culture) {
    // Call old method for old implementations:
    Log(timestamp, message);
  }
}

This way you can evolve your code without forcing every implementation of the contract to consume your changes immediately.

Hallgrim
I don't know how I missed reading this one, but yes, I 100% agree! Even more reason to reconsider using interfaces unless they really solve your problem well...
Mike Stone
Unfortunately Java and C# sharp have no multiple inheritance...
bwalliser
Can't you also do this without interfaces?
IanL
IanL, the point that interfaces have some drawbacks and should only be used when necessary.
Marcio Aguiar
@bwalliser : I would say FORTUNATELY they don't have multiple inheritance.
Andrei Rinea
Programming to an Interface is good practise.The problem I think people have is that they take "program to an interface" too literally.A Superclass can be an Interface.
Craig Norton
Multiple Inheritance is dangerous... very evil indeedy.
RWendi
I do both. I provide an interface, and an abstract base class on which implementations are based.
Jon Rimmer
If you intend to support both "old-style" and "new-style" Log() functionality, why not have LogSink implement both ILogSink and ILogSinkVersion2? The advantage is that the dependency structure is explicit, so...
j_random_hacker
... when all calling code has been moved over to use ILogSinkVersion2, then -- and only then -- you can remove the "implements ILogSink" clause from the LogSink declaration.
j_random_hacker
@j_random_hacker: I do not want to force my client to change their code. By using a baseclass instead of interfaces I think I can do this with less friction.
Hallgrim
@Hallgrim: If your class implements both interfaces, callers don't need to change at all -- they just continue using the old interface and the old behaviour. Right?
j_random_hacker
I dont see why you can't just add the second Log method to the original interface. That has the same results. On the other hand, if you want to change the implementation of the LogSink class, you force all clients to notify these changes, whereas they could ignore it when using just the interface.
MartinStettner
Don't forget that you can extend the interface as well. You can have ILogSinkVersion2 extend the ILogSink. This way no implementors or original ILogSink will get broken. "Open for extension, closed for modification" works for interfaces as well.
Danijel Arsenovski
+11  A: 

For me an interface should only be created when there's someone, somewhere which doesn't really care about who is implementing it as long as it's being implemented.

And that's the only place to use them, to define and agree on behaviour, any other use is probably misuse (some exception for particular cases allowed but generally speaking)

Jorge Córdoba
In this situation, I would actually prefer a dummy implementation to an interface... as long as the class is written correctly, both achieve the same goal.
Mike Stone
+7  A: 

Interfaces should be used with care - don't add too much abstraction when it is not necessary! The minimalistic approach is really good thing - it help for easier walk through the code after several months when nobody remembers the big interface hierarchy

m_pGladiator
+2  A: 

I can only see benefits. I for one never pass implementations as parameters. I only pass interfaces around. Its also useful when you are doing DI. Anyway. Who cares how a class is implement the consumer is only interested in the things it can use and an interface only gives him those things. Ok I admit it's a bit against the YAGNI principle but programming against interfaces becomes a habbit that you won't be sorry you did.

chrissie1
I worked on a project whose team would agree with you... I walked away hating interfaces more than liking them...
Mike Stone
WTF? Seriously. The public methods of your class is your interface. Its called encapsulation. Interface are supposed to be if you have multiple implementations of a class.
grom
+2  A: 

in an IDE, it means that when I try to browse to the source of this method being called... I get taken to an interface instead of some code that I can look at and see what is going on. This bothers me a lot, but also this is a real problem to me to hide where the implementation is coming from (sometimes it can be in non-obvious locations).

This is a problem of your IDE. With IntelliJ you don't have this problem (ctrl+alt+b).

It adds ANOTHER file to the system...

Agreed. Though, in my experience projects with "heavy interface usage" are easier to maintain.

bwalliser
I've actually had the opposite experience... I worked on a project with heavy interface usage, and it annoyed the hell outta me.
Mike Stone
Which IDE do you use?
bwalliser
Eclipse, though I prefer Emacs when I don't need the powers of an IDE (and the project I am talking about was long before I disovered Emacs... and I thought Eclipse was about as good as you could get)
Mike Stone
Try IntelliJ with Emacs keymap.
bwalliser
Actually, I have found I can work exclusively in Emacs quite productively and happily without missing the neat features (perhaps the lack of interfaces in the current codebase has aided that).
Mike Stone
I see where your antipathy to interfaces comes from. :)
bwalliser
Lol, I can see where you would think that, but actually I grew to dislike them from seeing them used excessively (in what I would call an antipattern) in my last company, before I was exposed to Emacs from my current CTO.
Mike Stone
+3  A: 

I used to use interfaces for mocking but at least in C# with rhino mocks you can get around that (you'll be making a lot of methods virtual though.). I agree that using interfaces just for this is a waste.

Another reason to use interfaces is for decoupling dependencies. Instead of one class depending on another they can both depend on an interface, one by implementing it and one by consuming it. I still use interfaces a lot for this. In a model view presenter architecture I usually have the presenter depend on an interface on the view instead of on the view class directly. This can be a very useful tool for resolving circular references between assemblies in your code too.

Interfaces are also a good tool to be more flexible in the way you order your work. If you want to implement and test high level behaviour first without getting bogged down in low-level dependencies you can just implement the low level behaviour (like persistence or writing to a file) as an interface and mock it in your tests. Later you can decide if you want to implement the interfaces you made this way or remove them completely if they're not useful anymore. Interfaces that are implemented only once and are only used within an assembly usually get removed.

Another thing to keep in mind that it's usually better to create small interfaces and implement more of them in a single class than create big monolithic interfaces. This improves decoupling and flexibility in your object design.

@Mike Stone: I often remove pieces of code that don't carry their own weight when refactoring. That includes interfaces that don't add anything useful. I agree that dummy implementations of classes as scaffolding can be better when you dont intend to use an interface in the final version. Interfaces require less typing beforehand but more refactoring to remove them when you're done. I don't always know beforehand what I intend to use though.

Mendelt
Dependency decoupling is a case where interfaces are quite useful, and I have done it before. I disagree with "and remove it later" though... I never clean up code that I initially intended to... I'd rather have an initial dummy implementation that I later fill in.
Mike Stone
+2  A: 

It's your choice if you want to go via mocking in TDD or not. TDD done the mocking way necessitates some use of interfaces. However, I do agree with you to some extent and feel that sometimes intensive interfaces mean that objects that are meant to be stubbed are instead mocked, and there's a wide difference between the two, or it's a case of TDD gone wrong.

Jon Limjap
I disagree with you here... I use TDD almost exclusively, but that doesn't mean you have to create unnecessary interfaces... it just means you may have to mock things now and then (which != creating an interface).
Mike Stone
Mike, yes I agree, but there are some cases that interfaces are nonetheless necessary. So yes, I also think that extensive interfaces might be yet-another-case of TDD gone wrong.
Jon Limjap
Edited my answer to reflect my agreement with you. Hope you don't mind Mike. :)
Jon Limjap
+5  A: 

I think the arguments that you provide against interfaces are not valid at all. For me programming is not about how many files you have in the application, or how easy it is to go to the source of something. Programming is about making things work the right way. Now, I've participated in the implementation of applications that expose extensive APIs and are used by many other developers. If I didn't use interfaces, I doubt I would be able to make users of these products happy. In short I think you are irritated by the IDE, as Roger said, not the interfaces themselves.

and you create an interface JUST TO ALLOW MOCKING

If you can mock an object, then it means that you can extend it and you have the flexibility to add additional functionality to the released product. So in fact there's no "just to allow mocking", mocking rather adds visibility to some design flaws you may have in the product. It is the same as with unit testing - only after you start doing it you realise how bad you clients felt with your product.

And finally, I also think that interfaces allow multiple inheritance in languages that otherwise don't support it. So my advice to you is to get the right tools for your IDE and don't confuse programming experience with the final result.

Slavo
"If you can mock an object, then it means that you can extend it and you have the flexibility to add additional functionality to the released product." Yes... so why is an interface needed if it is already flexible?
Mike Stone
The interface is needed to make it flexible. Sure, you can do mocking without interfaces, but i prefer not doing it for reasons I think you know. I'm saying that doing mocking adds visibility to the non-extensible parts of the system.
Slavo
In the end it depends on what you are building. But in my experience so many times I've made the mistake of making it in-extensible and not using interfaces (thinking I wouldn't need them), and then having to spend the time to redo the whole thing.
Slavo
Extract Interface is a very fast refactoring... also see my answer below, I don't think interfaces are really more flexible (you can easily design a class that is just as flexible).
Mike Stone
A: 

Interfaces are just a great mechanism that allow proxying/call-interception...

Mocking is just one application of that technique. Lazy loading is another very interesting application.

timvw
Neither mocking nor lazy loading require interfaces... I've done both without them.
Mike Stone
A: 

An issue with favouring mocking (or any kind of runtime substition) through subclassing, rather than through an interface, is that you can only override the behaviour of virtual members.

Invoking a virtual member requires an additional level of indirection via a Vtable and is slower than a final member. Whereas using an interface adds a compile-time overhead, but using virtual members adds a runtime overhead to every member invocation.

Surely, adding an interface **just to support mocking** is far preferable to slowing down your entire app **just to suport mocking**?

My preference, therefore, is to favour 'final by default'.

Steve Morgan
I feel that is a HUGE micro optimization that is ENTIRELY unnecessary... I prefer readable code and more flexible code to micro optimization. If you care enough about optimization to avoid using vtables, you belong in assembly code :-)
Mike Stone
The JVM **always** calls method as if they're virtual methods, even if the method is declared to be final.
Aviad Ben Dov
+23  A: 

Ok, I just wanted to thank everyone for all the great responses (I added comments on most of them for what I felt on each individual one)! It seems there is a strong division of people who firmly believe interface overuse is a good thing, and those who are on my side of the fence of believing they are a sign of a problem (and an antipattern).

Let me add 1 thing to all of you who seem to think creating an interface for just 1 class is a Good Thing:

Consider a class that does nothing in the constructor, except maybe set some fields and invoke some protected methods (which could then be overridden in both a mock and an alternate version of the class that some client decides they want to create). Now, how does this differ from an interface, realistically? Both are equally flexible to the client, but the class has the added benefit of being less complex. Essentially, the class is now an interface that also happens to be a default implementation.

If that clicks for you, you probably just realized why interfaces for 1 implementation bothers me so much.

Note that I am not talking about multiple inheritance... there are times where it is quite useful to be multiple things... but I say don't ANTICIPATE it... it is most likely not going to be needed... instead factor out the interface later when you see you DO need it (most IDE's have an "extract interface" refactoring tool).

There are 2 cases of interfaces being extremely useful that I can think of (off the top of my head) which I would jump on (and have) if I were going to implement such a thing:

  1. You have something that lends itself to a custom implementation... such as an Encoder type interface where there really is an obvious immediate need to have multiple options (most classes don't fall into this type of category in my experience).
  2. The class you are developing needs some kind of visitor pattern, where the code you are going to call may or may not need to be implemented by all clients... I'm talking about event callback sort of things, or higher order functions like map and reduce. (I guess this is kind of the same as option 1 now that I think on it more...)

Anyways, I'm not trying to say NEVER use interfaces... I'm trying to say evaluate it in each individual case, and try to see if there is going to be real benefit in adding the complexity to your system (there is no point in incurring unnecessary cost, right?)... like all patterns, patterns can be overused and applied when they don't actually give you any benefit, and I really believe interfaces are an overused pattern.

Mike Stone
Surely 'who firmly believe interface overuse is a good thing' is an oxymoron, as overuse of anything is not good?
belugabob
+7  A: 

Bottom line, if the interface is simplifying the test and making the implementation more complex than it needs to be, I consider it bad design... I would rather add a bit of complexity to the test and keep my implementation clean.

(ie, the interface should be simplifying the implementation, not the test).

Mike Stone
A: 

Classes are dead, long live interfaces. Qi4j

bwalliser
Looking at it, it sounds like something good in theory but in practice may not be as useful as it sounds... perhaps good principles to consider, but I strongly disagree with the quote you are referencing.
Mike Stone
A: 

Use case for creating an interface when there isn't an obvious need: The interface can make it easier to understand the basics of the class (looking at all of the public methods could add too much noise).

All language features are probably used too much (when they shouldn't be used) and too little (when they should be used). Overall I think that I have seen interfaces used a little too much.

James A. N. Stauffer
+15  A: 

I have rarely seen interfaces "over-used" in my experiences, but it is certaintly possible.

Knowing when to use:

  • An interface
  • Simple inheritence
  • Abstract base class
  • Interface AND an abstract base class
  • Encapsulation/helper classes

are keys to good designs. You can't learn enough about this, and we can't talk enough about it. We can talk about the "fringe" cases (all 300 classes in this library have interfaces), but I think that's a waste of time. We already know that "creating interfaces just to support unit testing" (or any other "just to support.." phrases you can think of) is not the right answer.

Yet there are some simple rules (the "is-a" relationaship test comes to mind). There are also some obvious situations where interfaces are used (plug-in architectures, for example). I will offer this thought...

Most piles of code in a library (think about the 300 classes mentioned above) have some public-facing interface that is significantly less large than "the entire code", and normally less large than what the library needs to support itself. Presenting this as a series of interfaces is what you want to be thinking about. Designing these interfaces requires a different train of thought than the code design - you are thinking about the consumption of your code, not the implementation of it.

By including this thinking, and designing interfaces, you will most certaintly be rewarded in the later stages of development (assuming this is a reasonable large system with more than one developer).

Bill
I don't think everyone finds it obvious that creating an interface for a test is bad... the link in my question and some of the responses here is evidence of that.
Mike Stone
As for libraries/frameworks... those are a different breed, and more interfaces may add real value (but not necessarily), but most people are developing applications, not frameworks, where I think interfaces have less value.
Mike Stone
+4  A: 

I would have added a comment....

For Eclipse, highlight the method and hit Ctrl-T, this will bring up the hierarchy of implementations for a method which will allow you to go to the implementation with a single click. This is especially useful with a Spring/Hibernate driving application where you want to skip all the proxies and reflection classes in debug mode.

On the broader topic of interfaces, I feel they're only needed when a factory of some sort is used, and preferably at component or application boundaries. A component that heavily uses interfaces internally and has a 1:1 interface:class ratio usually smacks of bad architecture or drinking the Spring Kool-Aid (essentially the same thing). Adding an interface for the sole purpose of Mocking is injecting test code into your production code and should be avoided at all costs.

Lastly, you should note that you can extract interfaces out of a class with ease when needed with Eclipse (and probably most other major Java IDEs as well) although you might need to rename your file outside of Eclipse, refresh, and then do an extraction back to the original name. This process allows you to effectively rename the class without breaking all the links to it, which will now utilize the interface. You can also specify which methods you'd like to extract, which will quickly show you via compile time errors where you're referencing the implementation class directly.

Munger
I just want to add that when in eclipse, I have a habit of CTRL+click, so unlearning that for an interfaced class is hard... nice to see Eclipse can do this though (for those real cases when interfaces are needed).
Mike Stone
+1  A: 

I couldn't agree more. Interfaces are like the "getters and setters" of the type system. Cruft that gets added everywhere whether it's necessary or not.

The trouble with interfaces is that they encourage inheritance and impose a hard hierarchy which makes your code brittle. Multiple inheritance? You should be using less inheritance, not more. Composition will set you free (and allow you to make all your classes abstract or final).

The mocking excuse is a red herring. Use automated specification-based testing and let the machine worry about mocking. Also, if you can't create real instances of any classes for testing because their methods may have destructive side-effects or have hidden dependencies on the state of the outside world, then you have flexibility problems that testing to interfaces is only going to encourage you to ignore.

Apocalisp
I have to agree about getters/setters - I see them as wasteful, requiring more effort to read the code. But OTOH I'm one of those who writes loads of interfaces and have never regretted it. I find they make code easier to browse, partly thanks to classes inheriting doc-comments from interfaces.
finnw
@Apocalisp: the link to "Use automated specification-based testing" seems to be broken.
Peter Mortensen
A: 

It seems to me that some of the difference in opinion here boils down to the issue of Test-Driven Development. Personally, I am a great fan of TDD, but that is off-topic here, so let us skip that discussion.

The motto of TDD is Test First. You might rephrase that as Tests First. To get into the proper state of mind for TDD, you not only need to code your tests first, you should also make sure that you ensure that you think of tests as a first-order concern.

Once we have established tests as a first-order concern, the reason for the many interfaces becomes much more obvious. In Test-Driven projects many (almost all) responsibilities will have at least two implementations: the "real" implementation and the mock/test-double/fake-object. Since the "real" implementation and the test-double(s) should not share any code (otherwise you are not properly isolating your tests) it makes sense to have a interface rather than letting the test-double override all the public methods of the "real" implementation.

To summarize: Many commenters are arguing that interfaces are used incorrectly, when they are only used to facilitate mocking. But when you use a test-double, no matter if it is a autogenerated mock-object or a manually written fake, you will have created a second implementation of your contract. You might argue that the second implementation of the contract is of lower value than the "real" implementation, so that you should not allow it to influence the structure of your "real" code. But then you are actually taking issue with Test-Driven-Development, which is another (and larger) discussion.

Edit:

I love TDD, and it is patently false to try and claim an interface is needed for it. TDD just means testing first, not creating an interface for anything you use. Mike Stone

I did not claim that you need interfaces for TDD. I claimed that TDD frequently require you to create and use multiple independent implementations of the same contract: the "real" implementation and the test-doubles. My point was that this situation is exactly where using interfaces is appropriate.

Rasmus Faber
Self-confrontational question: do you supply fake Strings for testing classes that depend on the String class? Why not?
Apocalisp
No. I usually draw the line at classes that I don't control and that have no sideeffects.
Rasmus Faber
I love TDD, and it is patently false to try and claim an interface is needed for it. TDD just means testing first, not creating an interface for anything you use.
Mike Stone
+3  A: 

Interfaces can be good for decoupling modules of your system that are at different levels of abstraction - for example, see the Separated Interface Pattern (http://martinfowler.com/eaaCatalog/separatedInterface.html). In this specific case, I can see there being value in splitting into interface and implementation, even if there is just one implementation.

For example, following Domain Driven Design principles, you try to have a separate, rich, entirely "business-focused" layer. This layer may still require access to objects that come ultimately from the database. By defining a "Repository" interface with operations defined purely in domain terms within the domain layer, and then having it implemented by a class in the infrastructure layer (which knows all the data access details), you eliminate the dependency of the domain on any infrastructure code (i.e. you could happily compile your domain layer without requiring the infrastructure code to be present).

However, I do agree that introducing interfaces just to support testing, or creating them as a matter of course for every class seems very wrong.

alasdairg
+185  A: 

Interfaces are useful in order to add a level of abstraction early on in the design process. It will benefit the modularity of your code. If you have a big enough project (one that warrants using mocking) interfaces are useful, though for small projects this is most likely overkill. They can be used more than they need to be certainly, but if you take to heart the following guidelines you will know when to use inheritance and when to use an interface. Your code reusability and scalability will increase greatly when interfaces are used where appropriate!

The old explanation of when to inherit works nicely:

  • Is a - inheritance

    Your class is a subclass of a more generalized class, e.g. HouseCat inherits from Feline because a house cat "is a" feline.

  • Has a - member field

    A LittleGirl has a cat, so obviously she should not be a subclass to HouseCat (she is not a cat). It is best that she "has a" HouseCat member field.

    class LittleGirl
    {
        int age;
        string name;
        HouseCat pet;
    }
    
  • Performs - interface

    Interfaces should be used when a class or group of classes all have similar functionality, but when there is no obvious line of inheritance. Think of them as a certificate that says "this object performs this functionality."

    For example, a HouseCat might inherit from Feline, but implement the ICanHasChesseburgers (or ICanHazChzbrgrsPlz) interface. That way you have a BurgerJoint class with a method public CheeseBurger Serve(ICanHasCheeseburgers patron) and be able to pass either Humans or HouseCats to the Serve method in order to feed them a Cheeseburger.

    This is useful because HouseCat does not inherit from Person nor vice versa. However, they both perform acts involving CheeseBurgers.

~ William Riley-Land

SoloBold
What an adorable example!
Stuart Branham
If you're not a teacher/professional software engineering trainer, you're in a wrong line of work. This is possibly the greatest way I've seen to date to explain how and when interfaces should be used!
Esko
+1 for using ICanHasChessebuger in a code example.
Nathan W
+1 for the laugh!
Tom
+1 for lolcat references :)
DanM
But some little girls can act like cats. ;-).
Gamecat
BEST EXAMPLE EVER
Ben Hardy
+1 Makes me want to have a cheese burger now :) and a cat too :)great explanation :)
Amitd
-1 for using ICanHasChessebuger in a code example.
zem
+4  A: 

Basic rule of thumb: If you only have a single class implementing an interface, and if you can't think of another possible implementation of the interface, you don't need an interface, at least not now. You can always refactor and add an interface later, if required.
I'd argue that you should not add interfaces because they are somehow required by your testing strategy. Unit tests are the most important tool developers have (in my opinion), but they should not force a particular design. Fix the test infrastructure if it forces interfaces on your design.

killdash10
+2  A: 

To the original poster - I'm with you. But I'll qualify that:

  • I love unit tests and TDD, because I can do my work without fluffing about with application servers. And unit tests are only effective long term if they're mocked.
  • I love being able to substitute implementations where it's useful to do so (which isn't often, just a few main services in any project).

But, with those two qualifications in mind, interfaces are way abused especially in big J2EE projects. I once had to debug a problem where there were 15(!) interfaces, stubs and facades between the bit of code that called a function and the implementation of that function. And the unit tests still weren't mocked properly. Just awful.

brad
Ouch! I feel your pain... on a side note, I love unit tests TDD too, and even more I love classes that are developed such that they can be mocked or their implementation replaced through subclassing if/when necessary (achievable without interfaces as it seems you are aware).
Mike Stone
A: 

I only use interfaces as a solution of last resort. I prefer abstract base classes over interfaces because it provides the ability to abstract base (common) code into one place. Additionally Visual Studio handles base classes better than interfaces.

That aside... The interface pattern is for providing reference to a related set of data items that can exist between unrelated data models (classes). I've often seen interfaces used on related classes instead of a base class (abstract or not) and it is one of my pet peeves...

Shire
+11  A: 

I wanted to post one final response after a little more thinking. I'm preparing for the barrage of down votes I might get with this.

I think this very issue shines a bright light on the issues that can arise with static typing. Notice I'm not saying strong typing, merely static. Really, all of this nonsense about interfaces is really just us TDD guys trying to be able to test each portion of our system in isolation. If we could duck type (signature based polymorphism) I guarantee you none of us would be rationalizing making those explicit interfaces.

What TDD aficionados like myself are saying is in the language I am using I need to use interfaces to get the level of decoupling I am after. I'm saying I need that decoupling to have an actual unit test, to verify 99% absolutely ;) that I have done my job. I would honestly rather just be able to use duck typing and only explicitly define an interface when I expect it to be of some use. One of the reasons I enjoy JavaScript is the ease with which I can create a mock object that looks and behaves like the real thing (as far as the injected class is concerned).

In closing allow me to summarize. I think the pain point isn't in either side's philosophy. One side is idealistic about how much decoupling they should be able to get and the other side is trying to deal with the practicality of applying such ideals in languages such as C# and Java. Both are good sides to be on. In the end, it comes down to understanding the limitations of your language and just making a judgement call on a case by case basis as to which side of the fence you'll choose to side with today.

Justin Bozonier
Dynamic languages lack such a mechanism specifically because there is absolutely no need for them, precisely because of duck-typing. I would call myself a TDD aficionado, but at the same time I can achieve decoupling without interfaces... it's quite easy even.
Mike Stone
(by the way, if you mean interface concept and not interface keyword, you should specify... I fell for it AGAIN)
Mike Stone
No I actually meant real interfaces. I think they have a role in terms of documentation. They help me understand what is meant to be supported. I could get without them in Python and Javascript but I think the language would be richer for them.
Justin Bozonier
Also Mike, how do you achieve decoupling without interfaces? Am I missing something obvious (aside from abstract classes)?
Justin Bozonier
Lets say A uses B. You achieve it by first making B a class that can be extended easy, and secondly by making it easy to change which instance of B an A is using... then A uses B but could also use a C (which extends from B).
Mike Stone
The only problem comes when C also needs to extend from D, in which case you still have options: C could contain a D and proxy calls to it (which may not work, or be very ugly), or you can AT THAT POINT extract the necessary interface. The key is waiting till it is really needed.
Mike Stone
A: 

The other reason for interfaces is when you want to offer maximum flexibility on implementation. That is you don't want to force the implementor to inherit from a base.

What if my class inherits from a different base? I am now forced to write a custom adapter that implements the particular base class being consumed rather than simply implementing a contract.

Glenn Block
Such cases are few and far between and don't warrant an interface unless the case HAPPENS... only framework development is when you might want to consider doing this without an immediate need, and I would argue it should still be considered carefully even then.
Mike Stone
+21  A: 

Read about the open/closed principle. Depend upon abstractions, not details. If you're depending on a concrete class, you're depending on details and there's no opportunity to change just one of two or more coupled components, you must change them all.

You say "JUST TO ALLOW MOCKING" as if it's a bad thing and then say that there's no real benefit. The benefit is in the decoupled design that allows me to use, for example, an Inversion of Control container that may have aspect-oriented programming features or support runtime dynamic code-composition, etc. By following these design principles, my options are always wide open. Being able to mock and perform interaction testing is one benefit I get and it happens to prove out the fact that my abstractions are aligned correctly according to the correct interaction boundaries.

When the testing via mocks goes well, it's a canary in the mineshaft that tells me whether things are designed correctly. When the testing via mocks goes poorly, I have a problem and it's usually reflected in other areas of the application, too, not just the mocks (again with the canary analogy).

Sure, sometimes you may not ever have an alternate implementation of ISomeFoo in which case it might have been a waste for that particular component. But if you ever DO need to have an alternate implementation, going and changing those 50 references to concrete PetrolSomeFoo to concrete HydrogenSomeFoo will hurt really bad, especially if someone of the changes involve other applications or integration scenarios.

I totally do NOT follow you on the files-on-the-filesystem argument. That matters so little as to be a non-argument. If your design concerns number of files on the filesystem, you might have a problem :) Or, you know what, put the ISomeFoo inside the same file as your first concrete implementation. There, 1 file.

Finally, your instinct that interfaces are smelly is not totally a bad one. But what is smelly is the statically-typed class-based languages like C#, Java, etc. that require strong interfaces (instead of, say, duck typing) in order to obtain the necessary abstraction to pull off the open/closed principle.

If we had duck typing, you wouldn't need so many interfaces and this conversation would be moot.

chadmyers
You can depend on abstractions without an actual interface. The abstraction is the class. Just because it has implementation details does NOT mean you are depending on them. The only case I see for eagerly using an interface where it isn't needed is framework development, PERIOD.
Mike Stone
The files argument is... another complexity in the system... just like more lines of code is more complexity. The complexity adds up, and before you know it you can have a project that is very difficult to maintain or navigate, even with IDE features.
Mike Stone
Consider: public void foo(Bar bar) { bar.foobar(); }This code would look the same when Bar is interface vs class... so where is the dependence on details? (yes, you CAN depend on details with classes, but you don't HAVE to if you do it right)
Mike Stone
While I disagree with your pro-interface attitude, I 100% agree with your duck typing point (my nickname is ducktyping on uservoice). It's not that you won't need "so many"... you need NONE, because there are none (since it solves no problems in dynamic languages).
Mike Stone
Mike: Read Robert Martin's articles and book(s) on SOLID principles, including the "Interface Segregation Principle" and the "Open Closed Principle". What you're suggesting above with classes being abstractions won't work in the long run
chadmyers
After reading up on the Open Closed Principle (http://en.wikipedia.org/wiki/Open/closed_principle), I am still not convinced that it requires interfaces... in fact the original usage had nothing to do with interfaces (the keyword anyways)
Mike Stone
You claim it won't work in the long run, but you don't provide any indication why... classes can be very extensible using the Open Closed principle WITHOUT interfaces.
Mike Stone
A: 

In C#, a lot of the concerns about encapsulating common use cases of interfaces and evolving interfaces by adding convenience methods can be addressed by (judicious) use of extension methods.

Doug McClean
+4  A: 

Yes. There are a billion programmers out there who've been taught design patterns so now they have to make everything fit into one of those nice neat boxes. Code's no good unless it's complicated.

A: 

Some of your concern around Visual Studio not handling code navigation via base classes could be solved by using ReSharper. I personally would not code against an Interface heavy solution without it.

Karthik Hariharan
+6  A: 

The original edict to "code to interfaces" seems to come from the GOF "Design Patterns" book. The important thing to realize from this is the interface they are talking about is not the Interface keyword/concept as it is most often currently interpreted as. The interface as they are writing about is just the public interface as represented by some class be it abstract or otherwise.(Interface didn't exist yet when the book was published)

Overriding some methods to provide your mock or stub is as a valid option as implementing an Interface to do the same. The trade-offs of inheriting from the class you're going to mock or via extracting and implementing an Interface are up to the details of the particular implementation.

craigb
A: 

Another way to look at interface is to look at it from productivity point of view. And yes, it has something to do with mocking. It's far easier to distribute work among different parts of a project among multiple group members if you are purely dealing with contracts (interface). Or at least if your base class implementation is very thin, then you can use that. Otherwise, if you aren't using interface and mocking your own thin implementation to test, you are totally dependent on the actual code, and guess what, when the developer that is working on that part of the code changes it, check it in and it break your build and left for the day.... Overused, perhaps, but as with all things, there are always advantages and disadvantages, just choose your poison wisely.

Jimmy Chandra
A: 

Use interfaces when you want to use dynamic proxies and aspect oriented programming, or runtime generated classes (mock objects is a particular example).

Adding interfaces is not breaking, so if your classes are not exposed outside it's OK to add them only when you'll really need it.

Nicolas Dorier
+4  A: 

To be flexible, think "factories".

If you define and use factory methods for object creation, it doesn't matter whether you're using a class or interface to the callers.

Think about it for a minute...

Suppose you start with a class:

public class Foo {
  Foo() {...} // package-access
}

and define somewhere in the same package

public Foo createFoo() { return new Foo(); }

Users can write

Foo foo = SomeFactory.createFoo();

Later you decide it would be good to use an interface so you can have alternate implementations. So you change to

public interface Foo {...}
public class SomeFooImpl implements Foo {...}

and change the factory method

public Foo createFoo() { return new SomeFooImpl(); }

This allows you to "have your cake and eat it too". The factory methods are a wee bit extra overhead, but give you flexibility later on down the pipe.

OK, now the confession: I don't regularly do this, but I'm thinking about doing it more and more. Thought I'd throw the idea out there and see who it sticks to and starts digesting them until it grows into a big blob that only Steve McQueen can stop.

Scott Stanchfield
ehh. How can SomeFeeImple implement Foo when Foo is a class?
Esben Skov Pedersen
In that partulcar example, Foo was changed to an interface
Scott Stanchfield
+1  A: 

I think you can overuse interfaces, however the reason for using them should be to decouple the components in a system. Even in small systems tight coupling between components is not a good thing (because customers always want more).

Tightly coupling an application to any database, file system or any other external resource will only tick your customer off when you give them some outlandish quote to change accessing a database to a webservice.

Korbin
+6  A: 

When you are considering writing anything which is likely to be a shared resource across multiple projects, then in my opinion, you simply must use interfaces. I'll give you an example:

Where I work (in a financial firm), we have an API which allows tradable product information to be accessed from any application:

Product p = productService.lookup(ProductCodeType.TICKER, "MSFT");

A decision was made that Product should be a class as opposed to an interface. Unfortunately, this has come to be a millstone around our necks. Why? Because Product is not quite as simple a class as it was first supposed to be.

We have a number of implementations of the ProductService which offer various caching strategies, static or dynamic views of the product universe. But we cannot do some very useful things which we want to do with the Products themselves, for example, hydrating properties in a background thread, using proxies to collect statistics, eagerly fetch and hydrate their properties, etc.

Had Product been an interface, we would have none of these restrictions. Interface is simply the mechanism the Java language designers used to "implement" the familiar design pattern.

oxbow_lakes
+5  A: 

I find that in most cases interfaces are seriously underused.

Using interfaces from the start allows you to divide behaviour and implementation. With complex applications this makes early programming a bit more complex but long term programming becomes a lot less complex.

Peter
I 100% agree with this one. Turns the question on its head
Steve McLeod
+1  A: 

I agree. I've been struggling with this question for ages now, and was going to raise a similar Stack Overflow question when I found this one.

I write a lot of Spring/Hibernate applications, and if conforming to the Spring/Hibernate standard way of structuring a web application, the procedural flow is usually recommended to go from action class --> service class --> DAO class, where the service and DAO classes have interfaces. So when I want to add a simple getter to get a new object/list out of the database and into my action, I have to write:

  - ServiceInterface.getObject()
  - ServiceImplementation.getObject()
  - DAOInterface.getObject()
  - DAOImplementation.getObject()

That's four changes in four different classes to add a simple getter!

If there's only one implementation per interface, I find this overkill. I still do it to remain consistent with the norm, and to remain consistent to other code in the same application which does require interfaces, but I still find it overkill.

It's little wonder languages like Ruby are so loved (by some).

If you're creating an interface for testing, then there are two implementations for your interface. Already passing your rule of thumb! :)
Aviad Ben Dov
The fact that people use Interfaces to increase rather than decrease the amount of boilerplate copy and paste programming in their designs isn't necessarily a problem with Interfaces as such.
reinierpost
+1  A: 

I think that this question points out one of the issues (flaws?) with the object oriented paradigm. I know that when I started out with OOP, I would use inheritance for everything. I would use the template pattern a lot and while this created productivity gains in the short run it would make class hierarcy headaches in the long run. In short, when I used inheritance, I would see simplicity and productivity in the short run and complexity and problems in the long run. The standard argument for using Interfaces and Object Composition.

Because of this I have moved to Interfaces and Dependency Injection. Has this become my "golden hammer" solution? Maybe, at this point I cannot say for sure. It is working well so far. I do see that my objects are far less coupled, but the overall structure of my system is more complex and I find myself writing more lines of "glue" code to have my objects interact.

Perhaps this will be the issue that ushers in the next paradigm. Personally, I'm learning a functional language (Erlang) in the next year to see what other programming perspectives there are out there.

Jamal Hansen
A: 

Sometimes I don't like having interfaces all around either, but quite frankly those two items you've mentioned are not real problems at all:

IDE don't show the implementation

Use a decent IDE, IntelliJ IDEA makes this pretty easy.

You probably would have the same problem using class inheritance anyway.

Which one the running implementation again?

Adds another file to the system

If you can still count or at least perceive the amount of files in your project, probably you don't need interfaces at all in first place.

OscarRyz
+3  A: 

You're right, referring to an interface conveys less information than referring to a concrete class. But this is generally a good thing. It keeps code simpler, which is usually better. Code written against an interface is only concerned with what the interface provides, and so all the extra information about what implementation you're using is irrelevant. I usually find code easier to read if it doesn't contain irrelevant information.

To respond to the two things you don't like about interfaces:

  1. This is a problem with modularity in general. The same thing happens when we decide to create a function somewhere instead of just writing the entire application inline within the main() method. This is a strange complaint. It seems you could use the same principle to complain about variables: e.g. you don't know what the value of a boolean variable will be at runtime, so how do you know whether to read the code in an if block?

  2. Don't add a separate file for the interface and its implementation if it bothers you. Do this instead:

:

public interface Foo {

    public void bar();

    ... other methods
    public static class BasicImpl implements Foo {
        public void bar() { ... }
        ... other methods
    }
}
Travis Wilson
+2  A: 

You asked:

What is so bad about having a mock that merely overrides some methods of the single implementation class?

The reason is simple: if you are to unit test something, it has to be done without interference of other classes' implementations. If you merely override a "production class", you could cause a situation where the test uses non-mock code - which means it could fail because of external influences (i.e. some other class' code).

Whether you agree to unit testing done this way or not is a different question - but this is why it's necessary to have something more abstract than merely overriding a production class.

And again: mocking is useful when you want to be sure, during testing, that you know exactly what input you'll be getting from external influences without needing to know their implementation details. This is extremely useful, especially when the implementations of other classes can take a long time to complete (major calculations) or require specific external software to complete (Message queues, DBs, etc. that might not be available for your unit-testing needs).

Aviad Ben Dov
A: 

I agree. C# uses interfaces to replace multiple inheritance. I don't really like it much but then Microsoft forgot to call me when they were designing the language ;)

Jay
This element was taken from Java, by the way.
reinierpost
+4  A: 

Well on a recent project, I took a plunge and used interfaces heavily. By that I mean that almost all the classes in the project implement at least one interface. Some implement 2 or more. But also the number of interfaces is far lower than the number of classes.

The possibilities of this have shocked my socks off!

Allow me to give an example. Two of the interfaces are Provider and Receiver.

The first methods built were two classes. One was a SymbolManager as a Receiver of market symbols. The other was a FileProvider as a Provider which is reading financial data from a file and passes it to the SymbolManager. At first it felt cumbersome putting the methods both in the SymbolManager and the Receiver interface. Same for FileProvider.

But the next requirement was to have multiple SymbolManagers each for a different "symbol" which is a financial instrument.

And then the requirement was to feed data to them from a single "provider" which was a data broker. Well the data broker feeds many symbols so they need to be multiplexed to the proper SymbolManagers.

So the ProviderService implements Provider and feeds data to multiple Receivers.

Next users need to send this data remotely across a network so now a ReceiverStub implements a Receiver and marchals the data across TCP/IP with a ProviderProxy receiving and passing to a Receiver.

Point is that more and more Receivers and Providers keep getting added AND it's very easy through configuration to connect them in various different ways.

I'm shocked at how often we keep coming up with more Provider and Receiver ideas.

The most power of all this, of course, is that when we add a new Provider or Receiver implementer, it can get connected to any other of the other existing objects just by injecting into the other object WITHOUT changing the older objects code.

In fact, it helps me to think of Interfaces as an easy way to make software operate internally similar to a "plug-in" architecture where you can add functionality to older code without changing the older code in any way.

It's nearly impossible to see the value of Interfaces until you get hit with a requirement later in a project or even after it's finished that you never accounted for when building it originally. If you made it loosely coupled you find it quick and easy to make the change usually. If not, it may be more painful and time consuming.

We have even taken this to a literal plug-in architecture by allowing users to create their own implementers of interfaces that get dynamically loaded via reflection. In fact, the GUI dynamically finds all classes in their DLL that implement certain interfaces and let's them pick from the list.

Now that I've built "loosely-coupled", pluggable architecture using interfaces, I can't imagine working the old way.

Wayne
I was not intending we never use an interface again, just simply saying we should think about it first. It is easy to extract interfaces later (Eclipse provides a refactoring action named exactly that). Just consider YAGNI, and add that interface at the time you discover it will be useful for a particular situation. That's my main point.
Mike Stone
+5  A: 

"Another file to the system" objection is so 1980's. So what? I'd rather have 100 source files that are small, clean and easy to understand than 2-3 files that are huge and full of highly coupled code.

The objections you present are superficial. What interfaces provide is a cleaner separation from a service and something that uses the service. If I want to know what time it is, I only need to look at the watch. I don't need to see all the little wheels and springs inside. And I don't really care if the watch is on my hand or it is a Big Ben: they both share a same interface.

Igor Brejc
This is all very well if you can tell from the naming, typing and comments in an interface what its members are supposed to do and how they work together. That is not usually the case, in my experience. You get a good idea but you often need to look up details in implementations.Code contracts can help here btw.
reinierpost
Code contracts are new thing in C#, so they aren't really a solution for pre-4.0 code. I agree that it's a problem if you have to deal with other people's code with interfaces that aren't specified well enough. But that doesn't mean your own have to be that way - if you follow the TDD approach, your tests are the specification. And using interfaces is _the_ way to do TDD. Not to mention inversion of control.
Igor Brejc
Let me give another example: ASP.NET MVC. Its power lies in the fact that most of the framework is exposed through interfaces, which makes extending and testing it much much easier than, say, WebForms. The only parts that are problematic to work with are the ones which are _not_ exposed as interfaces. HttpContext is one example of this. http://mikehadlow.blogspot.com/2008/08/taking-httpcontext-out-of-mvc-framework.html
Igor Brejc