Refactoring: extract and override factory method

I’m sure you have seen classes that initialize a lot of objects in their constructor. These classes may be hard to test because of those object creations I mentioned. To get around this problem we use Extract and override factory method refactoring so we can extend these classes and override some factory methods.

Let’s see the following code.

public class XmlPaymentManager
{
   
private PaymentTranformer
_transformer;

   
public
XmlPaymentManager()
    {
       
var readerPath = ConfigurationSettings.AppSettings["ReaderPath"
];
       
var writerPath = ConfigurationSettings.AppSettings["WriterPath"
];

       
var reader = new StreamReader
(readerPath);
       
var writer = new StreamWriter
(writerPath);

        _transformer =
new PaymentTranformer
(reader, writer);
    }

   
// ...
}

We can see here initialization of StreamReader and StreamWriter. We cannot use these classes for unit testing purposes because we don’t want to read and write files. If we do then we have integration tests as we may face file system issues. As a first step let’s move creation of PaymentTransformer class to separate method.

public class XmlPaymentManager
{
   
private PaymentTranformer
_transformer;

   
public
XmlPaymentManager()
    {
        _transformer = GetTransformer();
    }

   
protected PaymentTranformer
GetTransformer()
    {
       
var readerPath = ConfigurationSettings.AppSettings["ReaderPath"
];
       
var writerPath = ConfigurationSettings.AppSettings["WriterPath"
];

       
var reader = new StreamReader
(readerPath);
       
var writer = new StreamWriter
(writerPath);

       
return new PaymentTranformer
(reader, writer);
    }

   
// ...
}

Now we can create extended class that overrider GetTransformer() method. For testing purposes we use FakePaymentTransformer.

public class TestXmlPaymentManager : XmlPaymentManager
{
   
protected PaymentTranformer
GetTransformer()
    {
       
return new FakeXmlPaymentTransformer();
    }
}

Extract and override factory method helps you if you can extend the class you want to test. You may save a lot of time when you find larger hard to test classes and you can make them testable using this refactoring method.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    2 thoughts on “Refactoring: extract and override factory method

    • December 9, 2009 at 10:24 pm
      Permalink

      It doesn’t work like that. You have to make GetTransformer virtual in order to be able to call it. That works in java, where all the functions are virtual, but not in c#. So, it should look like this:
      class BaseClass
      {
      private string a;
      public BaseClass()
      {
      a = CreateMethod();
      }
      protected virtual string CreateMethod()
      {
      return “aaa”;
      }
      }
      class DerivedClass : BaseClass
      {
      protected override string CreateMethod()
      {
      return “bbb”;
      }
      }

    • June 17, 2013 at 5:50 pm
      Permalink

      I think the same thing can be achieved by using poor mans dependency injection.

    Leave a Reply

    Your email address will not be published. Required fields are marked *