Coding to Interfaces

What does it mean to program to an interface?

There are some wonderful answers on here to this questions that get into all sorts of great detail about interfaces and loosely coupling code, inversion of control and so on. There are some fairly heady discussions, so I'd like to take the opportunity to break things down a bit for understanding why an interface is useful.

When I first started getting exposed to interfaces, I too was confused about their relevance. I didn't understand why you needed them. If we're using a language like Java or C#, we already have inheritance and I viewed interfaces as a weaker form of inheritance and thought, "why bother?" In a sense I was right, you can think of interfaces as sort of a weak form of inheritance, but beyond that I finally understood their use as a language construct by thinking of them as a means of classifying common traits or behaviors that were exhibited by potentially many non-related classes of objects.

For example -- say you have a SIM game and have the following classes:

class HouseFly inherits Insect {
void FlyAroundYourHead(){}
void LandOnThings(){}
}

class Telemarketer inherits Person {
void CallDuringDinner(){}
void ContinueTalkingWhenYouSayNo(){}
}

Clearly, these two objects have nothing in common in terms of direct inheritance. But, you could say they are both annoying.

Let's say our game needs to have some sort of random thing that annoys the game player when they eat dinner. This could be a HouseFly or a Telemarketer or both -- but how do you allow for both with a single function? And how do you ask each different type of object to "do their annoying thing" in the same way?

The key to realize is that both a Telemarketer and HouseFly share a common loosely interpreted behavior even though they are nothing alike in terms of modeling them. So, let's make an interface that both can implement:

interface IPest {
void BeAnnoying();
}

class HouseFly inherits Insect implements IPest {
void FlyAroundYourHead(){}
void LandOnThings(){}

void BeAnnoying() {
FlyAroundYourHead();
LandOnThings();
}
}

class Telemarketer inherits Person implements IPest {
void CallDuringDinner(){}
void ContinueTalkingWhenYouSayNo(){}

void BeAnnoying() {
CallDuringDinner();
ContinueTalkingWhenYouSayNo();
}
}

We now have two classes that can each be annoying in their own way. And they do not need to derive from the same base class and share common inherent characteristics -- they simply need to satisfy the contract of IPest -- that contract is simple. You just have to BeAnnoying. In this regard, we can model the following:

class DiningRoom {

DiningRoom(Person[] diningPeople, IPest[] pests) { ... }

void ServeDinner() {
when diningPeople are eating,

foreach pest in pests
pest.BeAnnoying();
}
}

Here we have a dining room that accepts a number of diners and a number of pests -- note the use of the interface. This means that in our little world, a member of the pests array could actually be a Telemarketer object or a HouseFly object.

The ServeDinner method is called when dinner is served and our people in the dining room are supposed to eat. In our little game, that's when our pests do their work -- each pest is instructed to be annoying by way of the IPest interface. In this way, we can easily have both Telemarketers and HouseFlys be annoying in each of their own ways -- we care only that we have something in the DiningRoom object that is a pest, we don't really care what it is and they could have nothing in common with other.

This very contrived pseudo-code example (that dragged on a lot longer than I anticipated) is simply meant to illustrate the kind of thing that finally turned the light on for me in terms of when we might use an interface. I apologize in advance for the silliness of the example, but hope that it helps in your understanding. And, to be sure, the other posted answers you've received here really cover the gamut of the use of interfaces today in design patterns and development methodologies.

Coding to interfaces?

Just one possible correction:

To use the interface one can simply call the methods on an instance of the concrete class.

One would call the methods on a reference of the type interface, which happens to use the concrete class as implementation:

List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");

If you decided to switch to another List implementation, the client code works without change:

List<String> l = new LinkedList<String>();

This is especially useful for hiding implementation details, auto generating proxies, etc.

You'll find that frameworks like spring and guice encourage programming to an interface. It's the basis for ideas like aspect-oriented programming, auto generated proxies for transaction management, etc.

What does program to interfaces, not implementations mean?

Interfaces are just contracts or signatures and they don't know
anything about implementations.

Coding against interface means, the client code always holds an Interface object which is supplied by a factory. Any instance returned by the factory would be of type Interface which any factory candidate class must have implemented. This way the client program is not worried about implementation and the interface signature determines what all operations can be done. This can be used to change the behavior of a program at run-time. It also helps you to write far better programs from the maintenance point of view.

Here's a basic example for you.

public enum Language
{
English, German, Spanish
}

public class SpeakerFactory
{
public static ISpeaker CreateSpeaker(Language language)
{
switch (language)
{
case Language.English:
return new EnglishSpeaker();
case Language.German:
return new GermanSpeaker();
case Language.Spanish:
return new SpanishSpeaker();
default:
throw new ApplicationException("No speaker can speak such language");
}
}
}

[STAThread]
static void Main()
{
//This is your client code.
ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
speaker.Speak();
Console.ReadLine();
}

public interface ISpeaker
{
void Speak();
}

public class EnglishSpeaker : ISpeaker
{
public EnglishSpeaker() { }

#region ISpeaker Members

public void Speak()
{
Console.WriteLine("I speak English.");
}

#endregion
}

public class GermanSpeaker : ISpeaker
{
public GermanSpeaker() { }

#region ISpeaker Members

public void Speak()
{
Console.WriteLine("I speak German.");
}

#endregion
}

public class SpanishSpeaker : ISpeaker
{
public SpanishSpeaker() { }

#region ISpeaker Members

public void Speak()
{
Console.WriteLine("I speak Spanish.");
}

#endregion
}

alt text

This is just a basic example and
actual explanation of the principle is
beyond the scope of this answer.

EDIT

I have updated the example above and added an abstract Speaker base class. In this update, I added a feature to all Speakers to "SayHello". All speaker speak "Hello World". So that's a common feature with similar function. Refer to the class diagram and you'll find that Speaker abstract class implement ISpeaker interface and marks the Speak() as abstract which means that the each Speaker implementation is responsible for implementing the Speak() method since it varies from Speaker to Speaker. But all speaker say "Hello" unanimously. So in the abstract Speaker class we define a method that says "Hello World" and each Speaker implementation will derive the SayHello() method.

Consider a case where SpanishSpeaker cannot Say Hello so in that case you can override the SayHello() method for Spanish Speaker and raise proper exception.

Please note that, we have
not made any changes to Interface
ISpeaker. And the client code and
SpeakerFactory also remain unaffected
unchanged. And this is what we achieve by Programming-to-Interface.

And we could achieve this behavior by simply adding a base abstract class Speaker and some minor modification in Each implementation thus leaving the original program unchanged. This is a desired feature of any application and it makes your application easily maintainable.

public enum Language
{
English, German, Spanish
}

public class SpeakerFactory
{
public static ISpeaker CreateSpeaker(Language language)
{
switch (language)
{
case Language.English:
return new EnglishSpeaker();
case Language.German:
return new GermanSpeaker();
case Language.Spanish:
return new SpanishSpeaker();
default:
throw new ApplicationException("No speaker can speak such language");
}
}
}

class Program
{
[STAThread]
static void Main()
{
//This is your client code.
ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
speaker.Speak();
Console.ReadLine();
}
}

public interface ISpeaker
{
void Speak();
}

public abstract class Speaker : ISpeaker
{

#region ISpeaker Members

public abstract void Speak();

public virtual void SayHello()
{
Console.WriteLine("Hello world.");
}

#endregion
}

public class EnglishSpeaker : Speaker
{
public EnglishSpeaker() { }

#region ISpeaker Members

public override void Speak()
{
this.SayHello();
Console.WriteLine("I speak English.");
}

#endregion
}

public class GermanSpeaker : Speaker
{
public GermanSpeaker() { }

#region ISpeaker Members

public override void Speak()
{
Console.WriteLine("I speak German.");
this.SayHello();
}

#endregion
}

public class SpanishSpeaker : Speaker
{
public SpanishSpeaker() { }

#region ISpeaker Members

public override void Speak()
{
Console.WriteLine("I speak Spanish.");
}

public override void SayHello()
{
throw new ApplicationException("I cannot say Hello World.");
}

#endregion
}

alt text

What do programmers mean when they say, Code against an interface, not an object.?

Consider:

class MyClass
{
//Implementation
public void Foo() {}
}

class SomethingYouWantToTest
{
public bool MyMethod(MyClass c)
{
//Code you want to test
c.Foo();
}
}

Because MyMethod accepts only a MyClass, if you want to replace MyClass with a mock object in order to unit test, you can't. Better is to use an interface:

interface IMyClass
{
void Foo();
}

class MyClass : IMyClass
{
//Implementation
public void Foo() {}
}

class SomethingYouWantToTest
{
public bool MyMethod(IMyClass c)
{
//Code you want to test
c.Foo();
}
}

Now you can test MyMethod, because it uses only an interface, not a particular concrete implementation. Then you can implement that interface to create any kind of mock or fake that you want for test purposes. There are even libraries like Rhino Mocks' Rhino.Mocks.MockRepository.StrictMock<T>(), which take any interface and build you a mock object on the fly.

Should you always Code To Interfaces In Java

In general I agree with the other answers: use an interface when you know or anticipate change and/or different implementation, or go for testability.

But it's not always easy to know in advance what may change in the future, especially if you are not so experienced. I think the solution for that problem is refactoring: keep it simple (= no interface) as long as it is not needed. When the need arises simply do an "Introduce/Extract interface" refactoring (supported by almost all decent IDEs).

When you do it extract only those methods that are actually needed by the callers. Don't be afraid to extract more then one separate interfaces (if not all of the extracted methods are really coherent).

One driver of the refactoring might be the testing: if you can't easily test something with classes only consider introducing one/some interface(s). This will also allow you to use mocking which may greatly simplify testing in many cases.

Edit: based on Tarski's comment I've realized one more important scenario/adjustment to the previous statements:

If you provide an external API (for other [sub]projects, or really release it "to the wild") then using interfaces in the API (except for simple value classes) is almost always a good idea.

It will allow you to change the impl if you like without disturbing the client code. You will have a problem only if you also have to change the interface. Not breaking compatibility will be very tricky (if not impossible).

What is the definition of interface in object oriented programming

An interface is one of the more overloaded and confusing terms in development.

It is actually a concept of abstraction and encapsulation. For a given "box", it declares the "inputs" and "outputs" of that box. In the world of software, that usually means the operations that can be invoked on the box (along with arguments) and in some cases the return types of these operations.

What it does not do is define what the semantics of these operations are, although it is commonplace (and very good practice) to document them in proximity to the declaration (e.g., via comments), or to pick good naming conventions. Nevertheless, there are no guarantees that these intentions would be followed.

Here is an analogy: Take a look at your television when it is off. Its interface are the buttons it has, the various plugs, and the screen. Its semantics and behavior are that it takes inputs (e.g., cable programming) and has outputs (display on the screen, sound, etc.). However, when you look at a TV that is not plugged in, you are projecting your expected semantics into an interface. For all you know, the TV could just explode when you plug it in. However, based on its "interface" you can assume that it won't make any coffee since it doesn't have a water intake.

In object oriented programming, an interface generally defines the set of methods (or messages) that an instance of a class that has that interface could respond to.

What adds to the confusion is that in some languages, like Java, there is an actual interface with its language specific semantics. In Java, for example, it is a set of method declarations, with no implementation, but an interface also corresponds to a type and obeys various typing rules.

In other languages, like C++, you do not have interfaces. A class itself defines methods, but you could think of the interface of the class as the declarations of the non-private methods. Because of how C++ compiles, you get header files where you could have the "interface" of the class without actual implementation. You could also mimic Java interfaces with abstract classes with pure virtual functions, etc.

An interface is most certainly not a blueprint for a class. A blueprint, by one definition is a "detailed plan of action". An interface promises nothing about an action! The source of the confusion is that in most languages, if you have an interface type that defines a set of methods, the class that implements it "repeats" the same methods (but provides definition), so the interface looks like a skeleton or an outline of the class.

Program to an interface. What does it mean?

To put it simply, instead of writing your classes in a way that says

I depend on this specific class to do my work

you write it in a way that says

I depend on any class that does this stuff to do my work.

The first example represents a class that depends on a specific concrete implementation to do its work. Inherently, that's not very flexible.

The second example represents a class written to an interface. It doesn't care what concrete object you use, it just cares that it implements certain behavior. This makes the class much more flexible, as it can be provided with any number of concrete implementations to do its work.

As an example, a particular class may need to perform some logging. If you write the class to depend on a TextFileLogger, the class is forever forced to write out its log records to a text file. If you want to change the behavior of the logging, you must change the class itself. The class is tightly coupled with its logger.

If, however, you write the class to depend on an ILogger interface, and then provide the class with a TextFileLogger, you will have accomplished the same thing, but with the added benefit of being much more flexible. You are able to provide any other type of ILogger at will, without changing the class itself. The class and its logger are now loosely coupled, and your class is much more flexible.

What does it mean to program to an interface?

You are probably looking for something like this:

public static void main(String... args) {
// do this - declare the variable to be of type Set, which is an interface
Set buddies = new HashSet();

// don't do this - you declare the variable to have a fixed type
HashSet buddies2 = new HashSet();
}

Why is it considered good to do it the first way? Let's say later on you decide you need to use a different data structure, say a LinkedHashSet, in order to take advantage of the LinkedHashSet's functionality. The code has to be changed like so:

public static void main(String... args) {
// do this - declare the variable to be of type Set, which is an interface
Set buddies = new LinkedHashSet(); // <- change the constructor call

// don't do this - you declare the variable to have a fixed type
// this you have to change both the variable type and the constructor call
// HashSet buddies2 = new HashSet(); // old version
LinkedHashSet buddies2 = new LinkedHashSet();
}

This doesn't seem so bad, right? But what if you wrote getters the same way?

public HashSet getBuddies() {
return buddies;
}

This would have to be changed, too!

public LinkedHashSet getBuddies() {
return buddies;
}

Hopefully you see, even with a small program like this you have far-reaching implications on what you declare the type of the variable to be. With objects going back and forth so much it definitely helps make the program easier to code and maintain if you just rely on a variable being declared as an interface, not as a specific implementation of that interface (in this case, declare it to be a Set, not a LinkedHashSet or whatever). It can be just this:

public Set getBuddies() {
return buddies;
}

There's another benefit too, in that (well at least for me) the difference helps me design a program better. But hopefully my examples give you some idea... hope it helps.



Related Topics



Leave a reply



Submit