(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
According 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 useful.
"The guy above says he creates another interface to handle the new member(s). Nothing breaks."
I'm just guessing here, but it sounds like this guy comes from an old school COM background (I could be wrong, of course!). Makes me cringe to think of all of the code I've worked on where I've seen things like this:
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.
"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.
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.
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.
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.
I think that you describe there top-down design method.
You don't have to do it, but sometimes he really help.