Refactoring a static class to separate its interface from implementation-Collection of common programming errors

Static Classes can be transform into Singleton Objects.

Singleton Objects support interfaces.

Interfaces can be used for different implementations.

(1) Definition of Problem.

Suppouse you have a class that have static members.

StringsClass.cs

namespace Libraries
{
  public static class StringsClass
  {

    public static string UppercaseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is converted to uppercase,
      // and output stored in "Result"

    return Result;
    } // string UppercaseCopy(...)

    public static string LowercaseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is converted to lowercase,
      // and output stored in "Result"

      return Result;
    } // string LowercaseCopy(...)

    public static string ReverseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is reversed,
      // and output stored in "Result"

      return Result;
    } // string ReverseCopy(...)  

  } // class StringsClass

} // namespace Libraries

And, several code that uses that static elements, from that class.

StringsLibraryUser.cs

using Libraries;

namespace MyApp
{
  public class AnyClass
  {
    public void AnyMethod()
    {
      string Example = "HELLO EARTH";
      string AnotherExample = StringsClass.LowercaseCopy(Example);
    } // void AnyMethod(...)  

  } // class AnyClass

} // namespace MyApp

(2) Transform, first, the class, into a non static class.

StringsClass.cs

namespace Libraries
{
  public class StringsClass
  {

    public string UppercaseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is converted to uppercase,
      // and output stored in "Result"

    return Result;
    } // string UppercaseCopy(...)

    public string LowercaseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is converted to lowercase,
      // and output stored in "Result"

      return Result;
    } // string LowercaseCopy(...)

    public string ReverseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is reversed,
      // and output stored in "Result"

      return Result;
    } // string ReverseCopy(...)  

  } // class StringsClass

} // namespace Libraries

(3) Add code the allow class handle a single object.

StringsClass.cs

namespace Libraries
{
  public class StringsClass
  {
    private static Singleton instance = null;

    private Singleton()
    {
      // ...
    }

    public static synchronized Singleton getInstance()
    {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    public string UppercaseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is converted to uppercase,
      // and output stored in "Result"

    return Result;
    } // string UppercaseCopy(...)

    public string LowercaseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is converted to lowercase,
      // and output stored in "Result"

      return Result;
    } // string LowercaseCopy(...)

    public string ReverseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is reversed,
      // and output stored in "Result"

      return Result;
    } // string ReverseCopy(...)  

  } // class StringsClass

} // namespace Libraries

(4) Code that calls the class, should add the reference for the singleton.

StringsLibraryUser.cs

using Libraries;

namespace MyApp
{
  public class AnyClass
  {
    public void AnyMethod()
    {
      string Example = "HELLO EARTH";
      string AnotherExample = StringsClass.getInstance().LowercaseCopy(Example);
    } // void AnyMethod(...)  

  } // class AnyClass

} // namespace MyApp

(5) Define an interface, with similar declarations to the previous static class, and allow the singleton, to implement that interface. Omit the singletons members, in the interface declaration

StringsClass.cs

namespace Libraries
{
  public interface StringsInterface
  {
    string UppercaseCopy(string Value);  
    string LowercaseCopy(string Value);  
    string ReverseCopy(string Value);   
  } // interface StringsInterface

  public class StringsClass: StringsInterface
  {
    private static Singleton instance = null;

    private Singleton()
    {
      // ...
    }

    public static synchronized Singleton getInstance()
    {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    public string UppercaseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is converted to uppercase,
      // and output stored in "Result"

    return Result;
    } // string UppercaseCopy(...)

    public string LowercaseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is converted to lowercase,
      // and output stored in "Result"

      return Result;
    } // string LowercaseCopy(...)

    public string ReverseCopy(string Value)
    {
      string Result = "";

      // code where "Value" is reversed,
      // and output stored in "Result"

      return Result;
    } // string ReverseCopy(...)  

  } // class StringsClass

} // namespace Libraries

(6) In the code, where your are using your singleton, the previous class that contained static methods, replace the singleton for an interface.

StringsLibraryUser.cs

using Libraries;

namespace MyApp
{
  public class AnyClass
  {
    public StringsInterface StringsHelper = StringsClass.getInstance().LowercaseCopy(Example);

    public void AnyMethod()
    {
      string Example = "HELLO EARTH";
      string AnotherExample = StringsHelper;
    } // void AnyMethod(...)  

  } // class AnyClass

} // namespace MyApp

Now, you can add other classes that support the same declarations, with different implementation.

Cheers.