Extract method to class refactoring
August 21st, 2010The Extract Method refactoring is a basic refactoring technique where a part of a method is extracted out into a new method. This is used to:
- Simplify a complex method,
- Promote DRY, and
- Make testing easier
Here’s my Union-required contrived example:
interface IFoo { }
interface IFooRepository
{
IEnumerable<IFoo> GetFoos();
}
class FooProcessor
{
IFooRepository FooRepository { get; set; }
public FooProcessor(IFooRepository fr)
{
this.FooRepository = fr;
}
public IEnumerable<IFoo> GetProcessedFoos()
{
foreach (var foo in this.FooRepository.GetFoos())
{
// Do some processing on foo
// ...
// ...
yield return foo;
}
}
}
The inside of the loop in FooProcessor.GetProcessedFoos() might suit being extracted into a new method:
public IEnumerable<IFoo> GetProcessedFoos()
{
foreach (var foo in this.FooRepository.GetFoos())
{
yield return this.GetProcessedFoo(foo);
}
}
public IFoo GetProcessedFoo(IFoo foo)
{
// Do some processing on foo
// ...
// ...
return foo;
}
Now I can test the foo processing code without having to worry about setting up an IFooRepository mock just to pass in a single IFoo. Unfortunately the FooProcessor class still has the IFooRepository dependency, which I could work around by passing null to the constructor:
var fooProcessor = new FooProcessor(null); // test fooProcessor.GetProcessedFoo(...)
But that isn’t very clear, and when there are lots of tests and dependencies things can get very, very silly. Extracting the method into a separate class can solve the problem:
public IEnumerable<IFoo> GetProcessedFoos()
{
foreach (var foo in this.FooRepository.GetFoos())
{
yield return new GetProcessedFooMethod().Execute(foo);
}
}
public class GetProcessedFooMethod
{
public IFoo Execute(IFoo foo)
{
// Do some processing on foo
// ...
// ...
return foo;
}
}
Now the method can be tested directly without concerning FooProcessor‘s dependencies:
var getProcessedFooMethod = new FooProcessor.GetProcessedFooMethod(); // test via getProcessedFooMethod.Execute(foo)


