views:

1030

answers:

14

(In the context of .NET for what its worth)

I tend to not use inheritance and rarely use interfaces. I came across someone who thinks interfaces are the best thing since spit. He uses them everywhere. I don't understand this and hence the questions that follow. I just want a check on my understanding of interfaces.

If you are using interfaces everywhere, I'm assuming you can predict the future, your app requirements are nailed down and nothing will ever change in your app. For me, during early development especially, interfaces become a drag. The app is very dynamic through its life. If you need to subtract or add members to the interface, lots of stuff will break. The guy above says he creates another interface to handle the new member(s). Nothing breaks.

Isn't that composition? Why not use composition without interfaces? More flexible.

How does he handle the case where a member must be subtracted from the interface? Basically he doesn't. Things just break and that is great because now you can see all of the affected areas and fix them. Instead of figuring out more elegantly where all of the related code paths are, we should just rip out parts of classes through brute force?

I think of a software application as a graph. A complete graph is the worst case, having n(n-1)/2. This means every class talks to every class. A confusing spider web. n-1 is the best, in which their is a strict hierarchy of communication. Adding another interface just to compensate for a new needed member adds a vertici to the graph, which means more edges and a stronger realization of the n(n-1)/2 equation. Composition without interfaces is more like mixins. Only select classes use particular methods. With an interface, all classes are forced to use members, even if they don't need them. The composition/mixin approach doesn't add new unneeded edges.

+27  A: 

Interfaces don't force classes to use methods. They force implementing classes to implement all methods, but that's a different matter.

I like the way that interfaces separate out API from implementation. Admittedly this is also done with access modifiers, but interfaces make it clearer. More importantly, interfaces also make mocking easier - which means that you can unit test the classes which depend on the interface even before you've ever implemented it.

And yes, this means I often end up with an interface which only has a single production implementation. That isn't a problem in my view, because I've gained testability.

On the other hand, I don't write an interface for every class. I like to write interfaces where an object is essentially providing a service - authentication, data access etc. Plain data objects (even with significant behaviour) aren't as useful in terms of interfaces, IME.

Jon Skeet
Thanks on the clarified definition in your first paragraph. These classes aren't exposed to 3rd parties or as web services. Your last sentence applies. What did you mean by "...has a single production implementation"?
4thSpace
"has a single production implementation" = "There's only one implementation of the interface in the non-test code."
Jon Skeet
Still not following what you mean above. It sounds like you are very careful about your use of interfaces in general.
4thSpace
I try to be very careful about everything :) But my point is that even if I only have one real implementation of, say, IAuthenticator, it's still good to use an interface because I can use a mocking framework for unit testing other classes which depend on that interface.
Jon Skeet
The person I speaking about in the OP mentions the point about how interfaces are good for mocking also. I find something strange about saying you like interface also b/c of mocking. That seems a heavy influence on the decision. Sorta having the test framework influence the design.
4thSpace
Testability *certainly* influences the design. I don't see that as a bad thing at all. The thing is, testability usually goes hand in hand with other goodness such as low coupling.
Jon Skeet
It seems you err on the side of the fewest number of interfaces and prefer the concrete (class) type. Do you see interfaces as a restriction/constraint? That aspect of them is the main reason I rarely use them. Do you think that is a valid reason (no 3rd parties consuming API in this case)?
4thSpace
@4thspace: No, I still use interfaces a lot - certainly not the fewest I can get away with. It sounds like you're trying to read my answer in a way that supports your argument, whereas I'm probably closer to your colleague.
Jon Skeet
+8  A: 

I think both of you seriously misunderstand polymorphism. Acording to wikipedia,

The primary usage of polymorphism in industry (object-oriented programming theory) is the ability of objects belonging to different types to respond to method, field, or property calls of the same name, each one according to an appropriate type-specific behavior. The programmer (and the program) does not have to know the exact type of the object in advance, and so the exact behavior is determined at run time (this is called late binding or dynamic binding).

That's what makes interfaces so delicious.

"The guy above says he creates another interface to handle the new member(s). Nothing breaks."

Ugh. I'm just guessing here, but it sounds like this guy comes from an old school COM background (I could be wrong, of course! haha). Makes me cringe to think of all of the code I've worked on where I've seen things like this:

  • IWidgetManager
  • IWidgetManager2
  • IWidgetManager3

That's not a good way to work with interfaces. In my experience, I've seen both extremes: fear of changing interfaces to the point where new interfaces are created whenever new members are added, or not using interfaces at all and having a product that suffers from a high degree of coupling. You need to find a good balance. It isn't always the end of the world to change an interface.

What is the size of the project you're working on? It can be hard to see the benefit of interfaces if it is a relatively small size project. If, on the other hand, it's a project with several hundred thousand lines of code and is composed of many modules, the benefits become far more apparent.

unforgiven3
I'm not sure what you mean by "That's what makes interfaces so delicious" or your first sentence. Not following how you deduced such a conclusion with the info I provided. I'm subtly making the point that interfaces aren't a hammer for very nail, which has nothing to do with polymorphism.
4thSpace
You can achieve polymorphism through inheritance without using any interfaces. They aren't a prereq for polymorphism.
Pragmatic Agilist
I'm quite aware of that, Pragmatic Agilist. The question was about interfaces, though.
unforgiven3
+1  A: 

Interfaces make the most sense to me in the context of dependency injection and IoC frameworks. I like the idea that you can define a set of behaviors (methods) and "guarantee" those behaviors through the implementation of an interface. Now you can plug whole new functions into an existing system with a single assembly and a config file update.

Effective design of interfaces does require a good deal of forward planning, and I find they are most useful in the context of large systems and frameworks. When they're useful they're really useful. A few of my favorite:

  • IComparable (YOU decide how your objects compare against each other)
  • IQueryable (LINQ anyone?)
  • IDisposable (keep your using statement handy)
Dave Swersky
Yes and its a good description of when to apply. A large framework is similar to a custom app exposing its API, which is best done through an Interface.
4thSpace
+4  A: 

Interfaces have many useful situations. When you need to add a specific behavior to a class that can be found across a wide variety of classes, that's a perfect time for an interface. A good example is the IDisposable interface - you have some resource that when you're done, needs to go away in a timely fashion. Is it a database connection? Is it some window handle? Doesn't matter.

Another example would be when you really don't know how it should be implemented, such as an interface to an object that doesn't exist yet. Perhaps the object should be supplied by a client of your library, or must be implemented by a completely different module not under your control. You can basically design a contract for the methods available on the class.

That said, I only use them where it's needed. If I can do it with a regular class, or if it's something intrinsic to the particular object, I'll make it a class. There are some advantages to using Interfaces for every class as others have said, but that's so much extra overhead that I don't see a decent net gain on it. Most of the time, I've designed my class structures so that they're flat and wide, with as few dependencies as possible.

In summary: If you have common functionality required that's implemented dramatically differently, an Interface is just what you need.

Robert P
A: 

I think that you describe there top-down design method.
You don't have to do it, but sometimes he really help.

Avram
+2  A: 

"The guy above says he creates another interface to handle the new member(s). Nothing breaks.

Isn't that composition? Why not use composition without interfaces? More flexible."

You seem to be thinking of composition in terms of inheritance, as in, "I'll inherit all of these capabilities into this one object to do this job." That's a bad way to write code. It's like saying, "I want to build a skyscraper, so I'll learn every job there is to know, from how to create the blueprints on down to how to poor the foundation and install the lighting..."

Think of composition instead in terms of separate objects that each perform a single task. To do a complex job, I can now rely on these separate objects to perform their individual tasks. It's like hiring the architect and construction crew to build the skyscraper. I don't need to know in great details how they each do their job, just that they can do it. In code, this means injecting dependencies into an object to perform a complex tasks instead of inheriting.

So where to interfaces fit in? They're the contract between the individual objects. They allow you the ability to not care about individual, concrete implementations. They allow you to speak a common language with a bunch of objects that share the same responsibility, but may actually have different implementation. The interface becomes an abstraction to the object performing the task. I don't need to know how every single guy with a hammer works, just that he knows how to HitNail().

When you begin to compose complex system of code with lots of small classes that have single responsibilities, then you soon learn that you can run into serious problems if you rely too much on the concrete implementation of a given class, and that class begins to change... So instead of relying on the concrete implementation, we create an interface - an abstraction. And we say, "I don't care how you do JobX, only that you do it."

There are other benefits to interfaces like testing, mocking, etc... But those are not the reason to code to an interface. The reason is to create a system of code that isn't dependent on specifics and thus highly coupled to each other. This is why, with your graph thinking brain, you should be afraid of coupling a bunch of concrete classes to each other. Because changes in one of those classes will cause a ripple-effect.

When you couple yourself to an abstraction instead of a concrete class, you limit the coupling. You say, I"m only going to be coupled to the contract we both agree on, and nothing else." And if the class implementing that contract changes its internal way of completing its task, you don't care, because you aren't relying on a non-contract property or method. You're relying only on the agreed-upon contract.

Chris Holmes
"You seem to be thinking of composition in terms of inheritance..." - No. As mentioned, I rarely inherit. I was thinking in terms of little classes that expose a small number of members. Other classes compose these smallers classes by exposing them through a method/property. Better than interface?
4thSpace
+2  A: 

If you want to understand when to use interfaces, and what is their use, I think you should take a look at the book: Head First Desing Patterns.

This is the book that really helped me understand what is so cool about interfaces.

Before reading this book, I knew what an interface was, but I had absolutely no idea about when should I use them.

Martin
That's a very good book to demonstrate interfaces.
Gary Willoughby
In fact, this is just a very good book that I think every programmer should read :PThis one really changed the way I program / think about programming, something I have wished I had learned at school.
Martin
I also like to add Head First Object-Oriented Analysis and Design, This also is a nice book.
Ali
A: 

I'd refer to the .net design guidelines on this: http://msdn.microsoft.com/en-us/library/ms229013.aspx

There are a lot of reasons to use interfaces, but I also find that they're often overused for the wrong reasons. Interfaces provide much more flexibility when working with value types, and are incredibly useful when working with collections, etc, but when designing a class hierarchy for my own projects, I always try to think about simplicity first, and interfaces often lead to (unnecessarily) more complex situations.

My rule of thumb is to implement every BCL interface that makes sense, and only add my own interfaces into my designs when it actually provides something very valuable. Instead of having IWidgetManager, IWidgetManager2, etc... I'd much rather have abstract class WidgetManager and implement concrete methods as needed.

Reed Copsey
+1  A: 

It is about dependencies. You want your code to depend on interface types instead of concrete types where appropriate. For example, you might have multiple concrete types that all perform similar behavior but implement it differently. Do you want your code base to have dependencies on those multiple concrete types, or one interface? How flexible do you think your code base will be when you need to make changes?

To your point about not wanting to use public members by using composition, I would say you're just encapsulating unnecessary dependencies. If you want to use composition, then you greatly reduce dependencies by composing interface types instead of concrete types.

For a better explanation, try looking at the literature on inversion of control.

Pragmatic Agilist
A: 

This person sound like he misunderstood the concept of programming to an interface. It doesn't refer to programming using only the interface keyword in the .Net/Java or class with nothing but pure virtual functions in C++, The interface that are referred to in that principle are a high-level construct that encapsulates the low-level ones of a system. Like with multiplication, it encapsulates the idea of adding a number to itself a specific quantity of repetitions. But when we say 3 * 2 we don't care if it's 3 + 3, 2 + 2 + 2 or (2 + 2) + 2 where the part in parentheses is cached. So long as we receive a 6 from it.

As a matter of fact the concept of interfaces can be filled by an interface or abstract class or a combination of these as is the case with many of the GoF patterns. It's just that the interface keyword kind of clouds the water with ambiguity.

It's funny. This guy's kind of thinking is probably what's spawned comments such as the ones centering around StackOverflow episode #38.

Thedric Walker
+1  A: 

Interfaces help you keep the dependencies on the abstractions.

Code that uses the interface only depends on the interface, so you know that there are no artificial dependencies on the details. This gives you lots of freedom as far as changing code in the future, since you know exactly what should & shouldn't break when you 'fix' a bug or refactor.

In my opinion, it's the essence of good code design.

Jim Carroll
your tripping dude. his whole point is that the interfaces are being put in place *before the API is really known* - that's a really inapropriate way to use interfaces. They are a contract -- do you sign contracts without fulling understanding what you're getting into it?
alchemical
A: 

It sounds like your friend was seriously mis-using interfaces.

I've also seen web apps with interfaces all over the place. Some people seem to have the idea that an interface is somehow better than just a regular method signature. Simple parameters already provide us with a contract--in most cases I believe this is enough, and makes for simpler code.

It seems to me that interfaces are most useful in cases like IDisposable or ICollection -- where they point to a certain set of functionality to expect from an object. In these cases they appear to be the right tool for the job.

alchemical
A: 

We heavily use interfaces on custom UI elements, where each one is expecting a certain method to exist on another (and the interface forces that existence).

Jess
A: 

The primary use of an interface is to allow the variation of implementation allowing code to be switched at runtime. There are a number of reasons/rationale for doing this.

In the past some have argued that every class in the system should have an interface, but this is widely recognized as overkill. Interfaces are now used where instances of classes either can change as part of the system operation (to represent state): GoF patterns like Strategy and Command capture this use, and/or parts of the system need to be replaced for testing (ie. dependency injection). If developers are following test-driven development practices the key infrastructure objects will have interfaces. This allows tests to make "mocks" of these objects to test the system's flow-of-control. There is a relationship between this use of interface and the Liskov Substitution Principle (one of the principles of OO design)

A further use for interfaces which is less concerned with what is available to the caller, is the marker interface. Which is a way of associating metadata with the class definition. This may affect how the system views the object (for example allow it to be Serialized) or it might just serve as documentation.

andygavin