Design patterns: Strategy

The strategy design pattern is used in case different algorithms are implemented and shall vary dynamically dependent on the use case.

Very often, you can implement functionality in different ways. In most use cases you look at the pros and cons of the alternatives and select one. But sometimes you need the flexibility to offer different implementations and select the best one dynamically in context of the actual use cases. For example you want to read and save data in an encrypted format. In this case you may choose and implement a serialization strategy and an encryption strategy. Or you can offer different strategies and let the client application select the ones they need. This flexibility can be implemented by using the strategy pattern. You will implement different algorithms for one purpose. The context specific strategy will be chosen by the client which uses your context specific object.

The following example will show a possible implementation of the strategy pattern. In our application we will have different kinds of lists. These lists shall be sortable. There exist many different sort algorithms, all with their own context specific pros and cons. So you want to have the flexibility to select the algorithm depending on the kind of list you use.

Therefore we create a sort strategy by defining the according interface.

interface ISortStrategy<T>
{
    void Sort(List<T> list);
}

And we implement some algorithms for this strategy.

class ShellSort<T> : ISortStrategy<T>
{
    public void Sort(List<T> list)
    {
        //todo: implement sort algorithm
    }
}

class QuickSort<T> : ISortStrategy<T>
{
    public void Sort(List<T> list)
    {
        //todo: implement sort algorithm
    }
}

class MergeSort<T> : ISortStrategy<T>
{
    public void Sort(List<T> list)
    {
        //todo: implement sort algorithm
    }
}

At next we create a context specific class, in this case a customer list, which wants to use the sort strategy.

interface ICustomer
{
    string Name { get; set; }
}

class Customers
{
    private ISortStrategy<ICustomer> _sortStrategy;
    private List<ICustomer> _customers;

    public Customers(ISortStrategy<ICustomer> sortStrategy)
    {
        _sortStrategy = sortStrategy;
    }

    public void Sort()
    {
        _sortStrategy.Sort(_customers);
    }
}

Depending on their needs, the client application will have the possibility to select the best strategy dynamically. The following source code shows a console application which create the customer object instance and set the sort strategy.

class Program
{
    static void Main(string[] args)
    {
        ISortStrategy<ICustomer> sortStrategy = new MergeSort<ICustomer>();

        Customers customers = new Customers(sortStrategy);

        customers.Sort();
    }
}

In the example code the strategy was set by dependency injection via constructor. Of course, that’s one possible implementation only. You may also have the possibility to use the strategy as parameter of the sort function or to implement it in another way, for example as delegate if the strategy contains a single function only.

Werbung
Dieser Beitrag wurde unter Design Pattern, Designprinzip, Uncategorized veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit deinem WordPress.com-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s