1

I was browsing SO and came across this comment on an answer:

Why do we go through the ceremony of extracting an interface when we can DI a delegate to make it testable?

This articulated a thought I had earlier in the year. Is there anything inherently wrong with injecting pure functionality (function pointers, I guess) instead of interface implementations?

Ben Aston
  • 53,718
  • 65
  • 205
  • 331
  • since function pointers as a feature are language dependent, I take it so is your question. So what language? – Dmitry B. Nov 10 '11 at 04:46

1 Answers1

2

The word 'ceremony' in describing interfaces sounds suspiciously like a comment from a Ruby-ist who anti static-typing. With a good refactoring and templating tool, most of the ceremony goes unnoticed anyway.

While passing in a delegate has its place, IoC with interfaces is normally easier to implement, use, understand, and maintain.

Consider a typical constructor:

public class MyClass
{
  public MyClass(IAmEasyToUnderstand easy)
  {
    if (easy == null) throw new ArgumentNullException("easy");
  }

  public MyClass(Func<bool, int, int, Point> IAmNot, Func<bool> Clear, Action aboutAnything)
  {
    //multiple null checks.
  } 
}

public interface IAmEasyToUnderstand
{
   bool DoPointStuff(int a, int b, Point point);
   bool CanHazExecute();
   Action RunRun();
}

Now consider a class that returns an interface for consumption by another:

public MyClass
{
  //IFace
   public IAmEasyToUnderstand FindEasy();

  //Not Iface
   Func<bool, int, int, Point> ReturnPointStuffDoer();
   Func<bool> ReturnCanHazExecuteCallback();
   Action WowThisIsAnnoying();
}


var easy = myclassInstance.FindEasy();
var consumer = new EasyConsumer(easy);

....

var consumer = new EasyConsumer(
              myClassInstance.ReturnPointStuffDoer(),
              myClassInstance.ReturnCanHazExecuteCallback(),
              myClassInstance.WowThisIsAnnoying());

In looking at latter consumption example, the obvious cleanup would be:

var consumer = new EasyConsumer(myclassInstance);

which means you need an replace the class type with an interface for mocking.

Ritch Melton
  • 11,498
  • 4
  • 41
  • 54