Monday, 15 February 2010

Using Strategy and Adapter Patterns together

Both Strategy and Adapter patterns are most used design patterns I’ve found. Adapter pattern helps us making a class talkable and freely communicate with it which would not be possible otherwise. Strategy pattern also know as policy pattern allows freely selection of algorithm at run-time through the use of polymorphism.

You might find it useful to use both these patterns together. Here is an example how they would work with each other. In the following UML diagram I’ve a ItemSorting class which sorts list of items. It uses a specific sort algorithm to sort. The algorithm it uses for sorting is of type ISortStrategy which is injected to ItemSorting constructor.

image

Our assembly implements BubbleSort and QuickSort algorithms in-house. However, for some reason performance have not been very impressive so far. So we decide to buy third part sort algorithm which is sealed in a separate assembly. We want to use this algorithm in our code where ever we use legacy algorithm (i.e. BubbleSort and/or QuickSort) without breaking any existing code. But ThirdPartSort does not implement ISortStrategy so our ItemSorting class cannot use it.

Using Adapter pattern we can solve this problem. We create SortAdapter class which implements ISortStragegy interface. This class uses an instance of ThirdPartySort class to sorts items.

C# code implementing above behaviour.

    public class ItemSorting
{
private readonly ISortStrategy _sortHandler;

public ItemSorting(ISortStrategy sortHandler)
{
_sortHandler = sortHandler;
}

public void SortItems(List items)
{
_sortHandler.Sort(items);
}
}


    public interface ISortStrategy
{
void Sort(List items);
}

public class BubbleSort : ISortStrategy
{
#region ISortStrategy Members

public void Sort(List items)
{
Console.WriteLine("Will be sorting using bubble sorting algorithm");
}

#endregion
}

public class QuickSort : ISortStrategy
{
#region ISortStrategy Members

public void Sort(List items)
{
Console.WriteLine("Will be sorting using quick sorting algorithm");
}

#endregion
}

public class ThirdParySortAdapter : ISortStrategy
{
#region ISortStrategy Members

public void Sort(List items)
{
ThirdPartySort adaptee = new ThirdPartySort(items);

adaptee.SortItems();
}

#endregion
}


    class ThirdPartySort
{
private List _items;

public ThirdPartySort(List items)
{
_items = items;
}

public void SortItems()
{
Console.WriteLine("Will be sorting items using some alien algorithm");
}
}


   class Program
{
static void Main(string[] args)
{
List items = new List() { 1, 10, 20, 14, 9, 0 };

ItemSorting bubbleSortItems = new ItemSorting(new BubbleSort());
bubbleSortItems.SortItems(items);

ItemSorting quickSortItems = new ItemSorting(new QuickSort());
quickSortItems.SortItems(items);

ItemSorting thirdPartySortItems = new ItemSorting(new ThirdParySortAdapter());
thirdPartySortItems.SortItems(items);

}
}