Working with Interfaces Part Two – Decoupling

In the first part of this mini-series I talked about the basic use of interfaces, which is to provide a contract for your developers to work to. In this part, I’m going to try and demonstrate how interfaces can be used to make your application more flexible. This is probably the most common type of tutorial on interfaces you’ll see around the web, so forgive me for adding another.


Here’s an example of traditional style development, without interfaces:

<PRE>public class YoGenerator
{
public string Generate()
{
return “yo!”;
}
}

public class Greeter
{
public void SaySomething()
{
YoGenerator yoGenerator = new YoGenerator();

Console.WriteLine(yoGenerator.Generate());
}
}

public class Program
{
public static void Main()
{
new Greeter().SaySomething();
}
}</PRE>

So we’ve got a program that creates a new Greeter class and calls the SaySomething method on it. The Greeter class in turn calls a YoGenerator’s Generate method to output “yo!” to the console. This should all be fairly straightforward so far and if not, well, you’ve got bigger worries than what an interface is for.


So, the first step on making this a more useful application (I say that in the loosest terms, I’m not sure how much mileage you can get out of an app that says “yo!”) is to refactor by extracting an interface from the YoGenerator class and make YoGenerator inherit it:

<PRE>public interface IGreetingGenerator
{
string Generate();
}

public class YoGenerator : IGreetingGenerator
{
public string Generate()
{
return “yo!”;
}
}</PRE>

In terms of what our app now does, nothing has changed. It still outputs “yo!” to the console and it still does it using the same mechanism. However, we can now make an additional change which opens up more options:

<PRE>public class Greeter
{
public void SaySomething(IGreetingGenerator greetingGenerator)
{
Console.WriteLine(greetingGenerator.Generate());
}
}
</PRE>

That’s a fairly big jump if you’re not familiar with interfaces. We’re saying that SaySomething now takes one parameter – an instance of a class which implements IGreetingGenerator. That’s an important piece of information, because while you can’t directly create a new instance of IGreetingGenerator, you can pass implementing classes round in this way. And because IGreetingGenerator defines a method Generate, we’re able to call that on the instance we’re passing in. The final piece of the puzzle involves supplying SaySomething with an instance of a class that implements IGreetingGenerator. And remember how we changed YoGenerator to implement IGreetingGenerator…?

<PRE>public class Program
{
public static void Main()
{
new Greeter().SaySomething(new YoGenerator());
}
}</PRE>

So we instantiate a new YoGenerator which is also typeof IGreetingGenerator, and pass that to SaySomething. In the process, we’ve extracted SaySomething’s dependancy on YoGenerator… What does that mean for us? Well it means we can pass in new greeting generators to affect the behaviour of SaySomething, without actually having to change SaySomething’s code:

<PRE>public class DrunkenGreetingGenerator : IGreetingGenerator
{
public string Generate()
{
return “i lovzshh u mannn!!?!”;
}
}

public class Program
{
public static void Main()
{
new Greeter().SaySomething(new DrunkenGreetingGenerator());
}
}</PRE>

With a bit of forward thinking we can make the Greeter class work independently of other classes – we’ve decoupled it from YoGenerator and given it freedom to work with any class that implements IGreetingGenerator.

Related Articles:

    Post Footer automatically generated by Add Post Footer Plugin for wordpress.

    This entry was posted in c# practices interfaces. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

    7 Responses to Working with Interfaces Part Two – Decoupling

    1. Joe Ocampo says:

      You should extend this example to show how to integrate with Windsor or Structure Map.

      Overall good post, very well thought out.

    2. Brad Mead says:

      Nice!

      This is the Strategy pattern in action right?

    3. cramsay says:

      @Joe: How do you know what Part Three contains?? Is- is that you sat outside my house in your car? Are… are those binoculars?!

      @Brad: You tell me! I’m not familiar with very many patterns.

    4. Brad Mead says:

      I think so… This simple, effective concept appears to capture the same decoupling spirit as that which is termed Strategy in the “Head First Design Pattens” book. It’s primary… like chapter one. I like to link the real world usage to the commonly named pattern when possible. It helps gel the metaphor.

      Thanks for the post.

    5. I’m going to copy this example and put it in my app.

      It’s *brilliant* !

      ;)

    6. cramsay says:

      @ Ben: Every app needs a YoGenerator if you ask me.

    7. I’m partial to the DrunkenGreetingGenerator myself =)

      Great examples Colin. I agree with Joe that you should write a post on using interfaces with Windsor. I think there is alot of people out there that want to use Windsor that might not understand interfaces. This would give them a good example of using these features.

      Great post! keep it up!