Mark Needham

Thoughts on Software Development

Functional C#: The hole in the middle pattern

with 6 comments

While reading Real World Functional Programming I came across an interesting pattern that I have noticed in some code bases recently which I liked but didn’t know had been given a name!

The hole in the middle pattern, coined by Brian Hurt, shows a cool way of using higher order functions in order to reuse code in cases where the code typically looks something like this:

public void SomeServiceCall() 
{
	var serviceClient = CreateServiceClient();
 
	try 
	{
		serviceClient.MakeMethodCall();
	}
	catch(SomeServiceException someServiceException) 
	{
		// Handle exception
	}
	finally 
	{
		serviceClient.Close();
	}
}

The first and the third lines (initialisation and finalisation) are always the same but the service.MakeMethodCall() varies depending on which service we are using. The more services we have the more boring it gets writing out the same code over and over again.

In C# 3.0 we could reuse code in this situation by passing in a lambda expression which calls that method, allowing us to vary the important part of the method call while keeping the scaffolding the same.

public void SomeServiceCall(Action<TServiceClient> callService) 
{
	var serviceClient = CreateServiceClient();
 
	try 
	{
		callService(serviceClient);
	}
	catch(SomeServiceException someServiceException) 
	{
		// Handle exception
	}
	finally 
	{
		serviceClient.Close();
	}
}
SomeServiceCall(service => service.SomeMethodCall())

One of the things I’ve noticed with the ability to pass in functions to methods is that sometimes we end up making the code really difficult to read by doing so but when we’re dealing with services this seems to be one of the best and most obvious uses of Actions/Funcs in C# 3.0 and it leads to a more reusable and easy to understand API.

Written by Mark Needham

April 4th, 2009 at 11:41 am

Posted in .NET

Tagged with ,

  • Pingback: Lambdas in Java - IT Blog

  • http://bernd.eckenfels.net Bernd Eckenfels

    Do you know if this results in creation of an additional call object (carrying the args for the lambda expression)?

    In your example you have TServiceClient, if you would not have a Type, it would take more code, right?

    I yesterday hat the same problem (in Java), the whole in the middle is quite common.

    Unfortunatelly we do not have the lambda construct there (see the code in my german blog post:
    http://itblog.eckenfels.net/archives/441-Lambdas-in-Java.html
    )

    Greetings
    Bernd

  • Chuck

    Also known as Execute Around Method by Kent Beck…

    http://c2.com/cgi/wiki?ExecuteAroundMethod

  • http://www.markhneedham.com Mark Needham

    @Bernd – I think we had the carrying object (ServiceClient?) anyway even without passing in the service call as a function. A lot of the setup of the service is the same due to us using WCF to do service interactions.

    I think you probably would have more code if you didn’t have TServiceClient yeh.

  • http://bernd.eckenfels.net Bernd Eckenfels

    Thanks Mark, I was however refering to two things. One is the type which existed in your case (Saving some lines of code), the other thing however is the actual implementation of that lambda function. I think it will create a temporary call-container object on each invocation (just like the instance of the anonymous class you would use in java). Wonder if that is a correct or incorrect asumption on the runtime behaviour of that syntactic construct.

    Bernd

  • Pingback: Java 8: Lambda Expressions vs Auto Closeable at Mark Needham