Geeks With Blogs

News

Currently Reading

CLR via C#m
Under The Influence(of code) Abhijeet Patel's blog
This is a constant battle I fight in my head when I'm designing something. MSDN has an answer: When to use Delegates Instead of Interfaces, but it is nowhere as complete as I thought it should be. Good Object Oriented Design dictates using interfaces to decouple contracts from implementations.The premise is to enable substituting different implementations of an interface.Nothing new here just plain old good design guidelines. With the introduction of delegates in .NET 2.0 and lambdas in .NET 3.5 which are essentially functional programming concepts adds a new twist this situation. Using delegates basically allows substituting different implementations of a method having the same signature. So, the granularity of reuse is now back at the function level. The caller can substitute different methods confirming to the delegate signature and your callee is unaware of the actual method being invoked.

Following are some of the attributes of interfaces
  • Define a contract: A method can accept an interface as an argument thus enforcing a contract that callers must abide by.
  • Supply different implementations. These could be supplied dynamically at runtime usng policies if needed.
  • Group together logically related operations
  • Enable performing runtime type identification.Not advisable but still possible.


Following are some of the attributes of delegates
  • Define a contract:A method can accept a delegate as an argument thus enforcing a contract that callers must abide by.
  • Supply function definitions in place at the call site, thus avoiding creation of a new method and avoid suffering function call overhead
    i.e. the caller can pass functions definitions in place as arguments. Note that the functions that you can pass in are statically defined, unlike interfaces.
  • Provide an eventing model where in multiple methods can execute when the callee executes a delegate.
  • Write higher order functions.

Interfaces are typically used to model behavior(can do). Thus a class which implements an interface can be perceived as indicating that it exhibits the behavior indicated by the interface it implements. Any class method which has a matching signature as a delegate can be passed as a parameter to a method which accepts that delegate. There is no way to know this at a glance just by looking at the class definition.

Using interfaces can lead to a proliferation of implementing class hierarchies. This can lead to code bloat especially in cases where the implementation models something like a predicate or a strategy or just performs a simple action.

Using delegates as parameters, gives you an asynchronous programming model out of the box. You can call BeginInvoke on the delegate instance to asynchronously invoke the underlying method(s) if you desire to perform a non blocking operation. With interfaces, you would need to write some additional code to achieve non blocking behavior by either queuing a UserWorkItem or spawning a thread.

Using delegates can be a bit problematic in cases where there are multiple handlers attached to the delegate instance since firing the delegate will in turn invoke all the handlers for a multicast delegate. What if one of the handlers in the chain throws an exception?
How do you handle this? Do you need to notify the other subscribers of this? If so,how? Do you need to perform any sort of rollback? With interfaces you are guaranteed that there is only one object instance you are interacting with directly when you call any method on the interface.

When you accept a delegate instance,the caller could have captured local variable(closures). If these variables reference expensive resources or unmanaged resources, the callee could inadvertently cause leaks by either holding on to resource, since anytime you hold on to a delegate instance, you also hold onto the underlying object(root). If the object is not released timely the garbage collector will not collect it if there is a strong root reference to it.This means that if the object implements IDisposable you may be preventing resources from being released.

There are also some performance implications in using delegates vs interfaces. I'm no expert on this topic. Eric Gunnerson offers some insights on this.

In a nutshell there is no straight right answer. The correct answer depends on what is it that you are trying to do.
Design as always is a bunch of tradeoffs.Hopefully some of the guidelines above can help indicate the right path based on the situation you are in.


kick it on DotNetKicks.com Posted on Monday, November 24, 2008 9:52 PM C# | Back to top


Comments on this post: Interfaces Vs. Delegates

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Abhijeet Patel | Powered by: GeeksWithBlogs.net