So one of the standard Code Refactorings is
Extract Method.
You have some code like:
function Fa(){
a1 // A bunch of code
a2 // More code
a3 // Yet more code
}
function Fb(){
b1 // A bunch of code
b2 // More code
b3 // Yet more code
}
You decide that the code "A2" does some useful self-contained bit of work, so you rewrite to:
function X2(){
a2 // More code
}
function Fa(){
a1 // A bunch of code
X2() // Now a method call
a3 // Yet more code
}
function Fb(){
b1 // A bunch of code
b2 // More code
b3 // Yet more code
}
It's quite possible that other functions will turn out to have "a2" stuck in them, so you change them to call the new function as well. "a2" and "b2" were equivalent:
function X2(){
a2 // More code
}
function Fa(){
a1 // A bunch of code
X2() // Now a method call
a3 // Yet more code
}
function Fb(){
b1 // A bunch of code
X2() // Now a method call
b3 // Yet more code
}Oh boy, duplicate code removed!
Going back to the original two functions, what if "a2" and "b2" are the blocks of code that differ, while "a1"="b1" and "a3"="b3"? Then I guess by the book you factor out the 1s and 3s to two new functions, and end up with a total of four:
function X1(){
a1 // A bunch of code
}
function X3(){
a3 // Yet more code
}
function Fa(){
X1()
a2 // More code
X3()
}
function Fb(){
X1()
b2 // More code
X3()
}But if you have a lot of functions that share X1 and X3, bracketing the "useful work" starts looking weird after a while. At least, to me.
So in pseudo-C# 2.0, with anonymous delegates, I've would rewrite the above to
factor out the middle:delegate void AnOperation();
function TryX(AnOperation operation){
a1 // A bunch of code
operation(); // refactored middle
a3 // Yet more code
}
function Fa(){
TryX(delegate{
a2 // More code
});
}
function Fb(){
TryX(delegate{
b2 // More code
});
}Is that any cleaner? I don't know yet. It's 3 methods instead of 4. And the delegate signature doesn't have to be empty; it could take parameters that are set up in "a1" and cleaned up in "a3", to enforce some common error handling.
This occurred to me after
reading about Python 2.5's with statement; it's certainly not as elegant looking.