On a quest for the silver bullet..

Delegates, the Interface for methods

So, what’s with function pointers or delegates as .Net calls them? The Java-community hasn’t really been there, and the GOF-design patterns doesn’t really describe the use of them. They speak of interfaces.

Being a C# and Java developer, and thus a classical OO-guy, I haven’t really paid much attention to function pointers as a concept. I’m a big fan of interfaces and use them alot when modelling my code. The use of interfaces has also been the main focus for most of the design patterns out there.

Recently I’ve been looking towards dynamically typed languages like javascript, php, ruby, python and smalltalk, and I notice that the need for interfaces is a bit different here. I like to talk about how objects play roles, and I define those roles as interfaces in my code, letting different objects implement different (and several) roles. Using dynamically typed languages doesn’t change the way I think of roles, but it changes somewhat how I implement it. You do not really need explicit interfaces, you just need the objects to guarantee that the can do certain things. That they have certain methods. And this has been the whole point with interfaces all along.

Now in C# you have delegates. I have known this for a long time, but I haven’t really used it for much other than handling events. Now what does delegates have to do with all this? Quite alot actually.

I think of Delegates as “The interface for methods”. While classes can implement interfaces, and thus formally declares that they can play that role without revealing their true identity, methods can be passed around as delegates. The advantages with both interfaces and delegates are looser coupling, since it hides the objects true identity and lets several objects play the same role (also called polymorphism). Notice also that using delegates makes the code even looser coupled, since the object with the method that is passed around as a delegate, does not have to declare a formal contract or binding to that particular delegate.

Let’s play around a bit with this. The observer-pattern is a classic and simple design pattern, which is also quite common. The classic way, with interfaces, can look like this:

public class Observer : IObserver
{
   public void StateChanged(String stateinfo) {//..}
}    
 
public interface IObserver
{
   void StateChanged(String stateinfo);
}
 
public class TheObservedOne
{
   public void RegistrerObserver(IObserver observer) {}
}

You have the actual observer (Observer), that implements an observer-interface (IObserver). Then you have the observed objects, that can registrer one (or more, depending on your implementation) observer, which he will signal to. There is loose coupling: TheObservedOne does not know who is actually listening, only that it is someone playing the IObserver-role. That’s nice. But we do know one thing: Allthough Observer and TheObservedOne do not know about each other, they both know about the IObserver-interface, which among other things means they both have to reference the same assembly. So, Let’s do it with delegates:

public class Observer : IObserver    {
   public void StateChanged(String stateinfo) {}
} 
 
public delegate void StateChangedObserver(string status);
 
public class TheObservedOne
{
   public void RegistrerObserver(StateChangedObserver observer) { }
}

Now there is a delegate, and no longer an interface. But what happens here? Where’s the link between Observer and TheObservedOne? There is none! And that’s the beauty of it. TheObservedOne is still tied together with the delegate, but now Observer does not have to have any references to anything. So basically any method with the same signature as the StateChangedObserver-delegate (one string in, nothing out) can observe TheObservedOne.

This is how we configure Observer to observe TheObservedOne:

theObservedOne.RegistrerObserver(
    new StateChangedObserver(observer.StateChanged));

We just specify an objects method (in this case observer’s StateChanged-method), and voila. On the receiving end, TheObservedOne does this to invoke the method:

StateChangedObserver observer;
//..
observer("message");

It’s really very simple.

Another very nice feature with C#-delegates is that you can invoke several delegates at once! This fits perfect with the observer-pattern. Normally (using interfaces) when I implement the observer-pattern, I get chills if there can be multiple listeners. That means I have to implement some internal list of all listeners in the observed class, and all the boring and error prone work that goes along with that. Well, no more of that! With delegates this is built into the language:

StateChangedObserver del = null;
del += new StateChangedObserver(
    observer.StateChanged);
del += new StateChangedObserver(
    observer.StateChangedIgnoreStatus);
theObservedOne.RegistrerObserver(del);

now two methods will be informed every time theObservedOne calls the delegate. Very Nice! And the best part, theObservedOne doesn’t have to care how many observers there are, he will keep on calling the delegate(s) the same way no matter what:

observer("message");

To sum up. There are quite a few possibilites here for good design. And as you can see, delegates are actually the less verbose, less coupled way. When it comes to patterns, there are more patterns that fits delegates just as good as interfaces. Strategy pops into my mind as another perfect candidate.

All the being said. Don’t go do a delegate-frenzy in your code, replacing all interfaces with delegates. There is a time and a place for everything, and finding the right place is what good design is all about. I will still use alot of interfaces. Remember, Interfaces are about roles, and roles are about high cohesion. Roles is a great way to model your software, and interfaces is your number one helper there. You might say that delegates gives you lower coupling, but it might also give you lower cohesion, so apply it with care.

I think the lesson here is (at least that’s what I got out of writing this post): Use the tools at your disposal. But use them wisely.

-Tore Vestues

December 10th, 2007 at 0:23 (057)


3 Responses to “Delegates, the Interface for methods”

  1. Gøran Hansen Says:

    Hello Tore
    A cool sample of how you can implement the observer design pattern with using function pointers. I totally agree with you. Use the right tools for the right job.

    The cool think about pattern language is that they are not concerned about programming languages constructs. It’s up to you as an implementer to use the constructs available to implement the pattern.

    Keep up the good work. Reading your blog is fun!

  2. Tore Vestues blogs » Looping collections in C# Says:

    [...] Still a lot of code unfortunately, and the FindAll-method call isn’t really as clear and simple as it could have been either. I won’t go into details about the delegate-concept here, but if you do not understand how it works, I really advice you to take a look. It’s a powerful tool. (Look at my post Delegate, the interface for methods) [...]

  3. get backlinks Says:

    Really great informative blog post here and I just wanted to comment & thank you for posting this. I’ve bookmarked youi blog and I’ll be back to read more in the future my friend! Also nice colors on the layout, it’s really easy on the eyes.

Leave a Reply