Sometimes you have duplicated code, that is not easy to remove with “ordinary” coding approaches. Think about the following example. You have two or more methods that needs to be encapsulated with try-catch blocks.
protected void Commit(ObjectMapper mapper, bool nestedTransaction)
{
if (nestedTransaction)
return;
try
{
mapper.Commit();
}
catch (SqlCoreException exc)
{
...
}
catch (DirtyObjectException exc)
{
...
}
catch (MapperBaseException exc)
{
...
}
catch (Exception exc)
{
...
}
}protected void Flush(ObjectMapper mapper)
{
try
{
mapper.Flush();
}
catch (SqlCoreException exc)
{
...
}
catch (DirtyObjectException exc)
{
...
}
catch (MapperBaseException exc)
{
...
}
catch (Exception exc)
{
...
}
}
In that case, only the single call changes, everything else does not. So how can we prevent that stupid code duplication? The answer is, by using a delegate method.
private delegate void SafeCallDelegate();private void SafeCall(ObjectMapper mapper, SafeCallDelegate call)
{
try
{
call();
}
catch (SqlCoreException exc)
{
...
}
catch (DirtyObjectException exc)
{
...
}
catch (MapperBaseException exc)
{
...
}
catch (Exception exc)
{
...
}
}protected void Commit(ObjectMapper mapper, bool nestedTransaction)
{
if (nestedTransaction)
return;
SafeCall(mapper, mapper.Commit);
}protected void Flush(ObjectMapper mapper)
{
SafeCall(mapper, mapper.Flush);
}
As you can see, we removed the duplicated exception handling and outsourced it to an new method that takes a Delegate Method as a parameter. This delegate calls the original method. That’s elegant, isn’t it?
I wish you good coding sessions.
Cheers
- Gerhard
February 7, 2008 at 3:53 am
Nice post, and just so you know, there is already an “Action” delegate defined in the .net framework 3.5 if you are using it. That way you wouldn’t have to define your own delegate.
It would look like this:
private void SafeCall(ObjectMapper mapper, Action call)
February 7, 2008 at 8:09 am
Cool. Did not know about the Action Delegate. I will have a look at it. Thanks for the info.
February 7, 2008 at 2:19 pm
This is so straight forward, yet I never thought of it. Thanks!
February 7, 2008 at 6:16 pm
what chris said… good post!
February 10, 2008 at 9:56 am
Never thought of it – cool!
February 12, 2008 at 2:39 pm
I use a pattern like this when connecting to a service that fails intermittently and where a single retry fixes 99% of problems.
In the SafeCall method (I called mine Nanny) you can try the call another time (or many more times) upon an exception.
September 12, 2008 at 9:38 am
I use a pattern like this when connecting to a service that fails intermittently and where a single retry fixes 99% of problems.
In the SafeCall method (I called mine Nanny) you can try the call another time (or many more times) upon an exception.