OK. I am learning design patterns. Every time I see someone code an example of a design pattern they use interfaces. Here is an example:
http://visualstudiomagazine.com/Articles/2013/06/18/the-facade-pattern-in-net.aspx?Page=1
Can someone explain to me why was the interfaces needed in this example to demonstrate the facade pattern? The program work if you pass in the classes to the facade instead of the interface. If I don’t have interfaces does that mean
10
Interfaces are unrelated to Design Patterns. They are about Object-Orientation. In OO, the type of an object is defined by its behavior, i.e. by the protocol it speaks (its methods).
Classes in languages like Java and C#, however, also define representation (fields) in addition to behavior (methods). One of the basic tenets of OO is that objects cannot know the representation of other objects even of the same type. However, if you use classes as types, other objects of the same class can know the representation of other objects, even private
fields. Therefore, using classes as types breaks OO. (Unfortunately, in both Java and C#, classes are types.)
The only way to do object-oriented programming in Java or C# is to use classes only as factories (i.e. only directly after new
) and never as types (i.e. never as the type of a field, return type or parameter type of a method or type argument to a generic type, never cast to a class, never use it with instanceof
). And as types, use only interfaces, not classes (and certainly not primitives in Java).
That’s what interfaces do: they enable object-oriented programming in Java and C#, without them, OOP would simply be impossible in those languages.
8
Think of an interface like a Contract. It’s a way to say, “These classes should follow these set of rules.”
Let’s use an example and call it IAnimal
. We could say that the interface defines two methods Run
and Walk
. It’s a way to say, “I MUST be able to call Run, Walk, etc. on classes which implement IAnimal.”
Why is this useful? You may want to build a function which relies on the fact that you must be able to call Run and Walk, for example, on the object. You could have the following:
public void RunThenWalk(Monkey m) {
m.Run();
m.Walk();
}
public void RunThenWalk(Dog d) {
d.Run();
d.Walk();
}
… and repeat that for all objects which you know can run and walk. However, with your IAnimal interface, you can define the function once as follows:
public void RunThenWalk(IAnimal a) {
a.Run();
a.Walk();
}
By programming against the interface, you are essentially trusting the classes to implement the intent of the interface. So in our example, the thought is “I don’t care how they Run and Walk, so long as they Run and Walk. My RunThenWalk will be valid as long as they fulfill that agreement. It functions perfectly well without knowing anything else about the class.”
You can think of the main purpose of interfaces as allowing code to be abstract as opposed to specific. In a language with strong type safety, it allows you to treat multiple classes with similarities the same without needing to know which specific one of these types is being used.
For example, you could have an interface for People in which several child classes extend. You could then have a method that deals in people, accepting any or all types of classes that implement People without any concern for what they are beyond that. This is also provided by other forms of inheritance, but interfaces have the special restriction that they themselves can’t have an implementation.
I think Larsenal has given the best answer so far, but I’d like to expand on it to give a concrete example from working enterprise-level code (not in C#, but another ECMAScript-based language). In my code, I can treat Classes that are fundamentally different things as if they were the same from the viewpoint of the client code.
In my application, I have an IPaging Interface that defines functions like nextPage(), previousPage(), etc. This Interface is implemented by View Classes, but also by Controller Classes. What this allows me to do is bootstrap the application with a View that directly implements IPaging that gets passed to the Application’s currentPaging variable. This View is already up and running while the Controllers are loaded with the data they need to proceed. This gets something interactive in front of users right away.
Once they’re past that View, the Application’s currentPaging variable is then given an instance of a Controller that implements IPaging. That Controller might then implement IPaging by calling those same functions on an IPaging View (that might again have IPaging Views inside it that allow nested, hierarchical navigation), or it might implement IPaging a different way, by swapping out pages of data to a View that has nothing to do with IPaging. The choices are literally limitless, and I can use the same Application framework with Views or Controllers that are customized to be slightly or very different based on the requirements we get. And our clients, like most clients, are nuts–so we have to be as flexible as possible.
I have never regretted using an Interface when perhaps there are only one or two implementations, but I have dearly regretted not using an Interface when I need an implementation that doesn’t inherit from the same base Class and I didn’t use an Interface. And once you have references to a specific Class spread all through your codebase and referenced from multiple projects, it’s tough to put the genie back into the bottle.
One advantage of Interfaces that I get in the language I use (that I suspect you could also have in C#) is that I have the choice to load in implementations of the Interfaces I use at runtime from an external source. The loading Application doesn’t need to compile in the Class definitions of the loaded implementations–it only needs the definition of the Interface to be able to cast to that Interface. Interfaces, by definition, have virtually no code in them.
I try to explain it in terms of the article you linked to: the use of interfaces makes it possible to create unit tests for the VehicleFacade
, to test that class in isolation. This can be accomplished by providing mock implementations of IEngineController
, ITransmissionController
, and so on, instead of using the real EngineController
, TransmissionController
etc.
Of course, those interfaces also allow to create different vehicles from different engine controllers, different transmission controller etc. and combine them freely. In real world scenarios, however, I expect the first use case (tests) to occur much more often then the second.
The article you referenced is a terrible example for gaining an appreciation for what makes interfaces useful. It took me a really long time before I finally had that “aha” moment on what makes interfaces useful. The reason for it was because I thought of interfaces as glorified base classes whose name is twisted to sound action oriented, just like the article you referenced. It’s no wonder I had this misperception because most articles talking about interfaces do the same thing.
The problem I had with “appreciating” interfaces was that they always seemed to morph into abstract base classes because it made the most sense. The alternative was to declare the interface, declare a derived(base) class of the interface that implemented many of the common methods that the concrete derived classes all shared. It didn’t make sense to have 2 classes for most every interface just to provide the plumbing when 1 would do. So the interface inevitably simply switched to being an abstract base class.
My “aha” moment happened when I realized that even though the interface name was “action-oriented” it really was just a base class by a different name. Thus, IEngineController isn’t really an interface, it is an EngineControllerBase Class. What I realized was that interfaces are most useful when they aren’t tied into the derived class implementation, but instead describe distinct actions or capabilities in themselves.
Thus, IEngineController would be better (and provide for a far more illustrative article) if it was called IStartStoppable OR even have 2 separate interfaces. IStartable, IStoppable. At least for me, once I got past the definining interfaces as glorified abstract base classes stage then the value of interfaces start to shine.