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!”;
}
}</p>

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: `

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

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: `

public class Greeter
{
public void SaySomething(IGreetingGenerator greetingGenerator)
{
Console.WriteLine(greetingGenerator.Generate());
}
}
` 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…? `
public class Program
{
public static void Main()
{
new Greeter().SaySomething(new YoGenerator());
}
}
` 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: `
public class DrunkenGreetingGenerator : IGreetingGenerator
{
public string Generate()
{
return “i lovzshh u mannn!!?!”;
}
}</p>

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.

Why ALT.NET?