Rob Smyth

Tuesday 9 August 2016

Revitalizing Legacy Code - Properties returning concrete types

You have a legacy code base that has properties returning concrete types. This makes unit testing (UT) very difficult. To change the signature to use an interface requires lot or refactoring and therefore risk of an error refactoring. Here is an approach to incrementally refactor these properties out of the code base.

To provide an alternative add another property to the type with a suffix like "I" that returns the appropriate interface. This become the base property with the concrete property referencing this new property. This enables new or code being changed to migrate to the new property incrementally. Once the old property is no longer used it will be deleted.

Legacy code:

  public class WidgetA
  {
     public WidgetB PropertyB
    {
      get
      {
        // whatever stuff done here
      }
      get
      {
        // does other stuff here
      }
  }

Testable (incrementally) legacy code:

  public class WidgetA
  {
     [Obsolete("Use  PropertyBI instead")]
     public WidgetB PropertyB
    {
      get { return (WidgetB)PropertyBI;  }
      set { PropertyBI = value; }
    }

     public IWidgetB PropertyBI { get; set; }
  }

The use of the ObsoletAttribute ensures that developers will see the property struck out in intellisense to promote useage of PropertyBI instead.

When the old, concrete type, property is no longer used it will be deleted and the "I" suffix property renamed to replace it.

Nice incremental refactoring of the code and allowing for incremental unit testing.

No comments: