Strategy and Decorator Pattern


It’s been a long time since I posted anything, been very busy with work. Many things have changed and I am currently working as an independent contractor.  My latest gig at the moment is working on a WPF product! 🙂 woo hoo!

Today I’m going to talk about using the Strategy and Decorator Pattern together, as it turns out they work pretty well together. Strategy pattern is a good way to encapsulate your algorithms, or in my case I want to use it to encapsulate reusable code, following the principle to keep it DRY. With the introduction of Action and Func classes in .NET framework, I have found that writing callbacks to be so much more accessible. For instance, you may sometimes need to repeat lots of Try…Catch statements in your code, and find that hard to keep DRY. This is where using callbacks are useful, like so…

private void ExecuteSomeMethod()
{
    SomeManager someManager = new SomeManager();
    WithExeptionHandling(someManager.Execute);
}

private void WithExeptionHandling(Action callback)
{
    try
    {
        callback();
    }
    catch(Exception e)
    {
        Logger.Log(e.Message);
        throw;
    }
}

This block of code becomes a good candidate for re-usability, and there are heaps of such blocks of code. For instance, logging code to log start and end perhaps for performance monitoring. Another example is transaction scopes, as well as opening and closing of database connections. Another advantage of using these “strategies” is that it coerces the developer to use these conventions and learn good habits.

First of all, I create an interface and a abstract base class to encapsulate the common behavior, as well as to construct the decorator behavior for my strategies.

public interface IStrategy
{
    StrategyResult Execute();
}

public abstract class BaseStrategy
{
    private readonly Func function;
    private readonly IStrategy strategy;

    protected BaseStrategy(Func func)
    {
        function = func;
    }

    protected BaseStrategy(IStrategy strategy)
    {
        this.strategy = strategy;
    }

    protected StrategyResult InternalExecute()
    {
        if (function != null)
        {
            return new StrategyResult(function());
        }
        return strategy.Execute();
    }
}

I’ve create three strategies for this exercise, namely exception handling, transaction scope and logging. Here’s the exception handling strategy.

public class ExceptionHandlingStrategy : BaseStrategy, IStrategy
{
    public ExceptionHandlingStrategy(Func func)
        : base(func)
    {
    }

    public ExceptionHandlingStrategy(IStrategystrategy)
        :base(strategy)
    {
    }

    public StrategyResultExecute()
    {
        StrategyResult result;
        try
        {
            result = InternalExecute();
        }
        catch (Exception e)
        {
            result = new StrategyResult(e);
        }
        return result;
    }
}

Here comes the decorator pattern. If you have notices in the abstract base class earlier on, I have 2 constructors, one which takes an IStrategy.  This allows me to wrap many strategies together, essentially getting a chaining effect. For instance, I could easily construct a strategy that logs my method start and end, that handles exception as well as wrap a transaction scope around the call. The possibilities are endless! 🙂

To make it easier to construct these decorated chaining effect, I created a factory as well as Extension Methods to make it much sweeter to construct.

public class StrategyFactory
{
    public IStrategy CreateExceptionHandlingStrategy(Func func)
    {
        return new ExceptionHandlingStrategy(func);
    }

    public IStrategy CreateTransactionScopeStrategy(Func func)
    {
        return new TransactionScopeStrategy(func);
    }

    public IStrategy CreateLoggingStrategy(Func func)
    {
        return new LoggingStrategy(func);
    }
}

public static class StrategyExtensions
{
    public static IStrategy WithExceptionHandling(this IStrategy strategy)
    {
        return new ExceptionHandlingStrategy(strategy);
    }

    public static IStrategy WithTransactionScope(this IStrategy strategy)
    {
        return new TransactionScopeStrategy(strategy);
    }

    public static IStrategyWithLogging(this IStrategy strategy)
    {
        return new LoggingStrategy(strategy);
    }
}

So now to wrap it all up with sample code that makes use of all these.

int top = 1;
int bottom = 0;
var factory = new StrategyFactory();

var strategy =
    factory.CreateExceptionHandlingStrategy(() => top / bottom)
        .WithLogging().WithTransactionScope();

StrategyResult result = strategy.Execute();

Console.WriteLine("Result Has Error: {0}", result.HasError);

As you can see, it’s easy now to chain your strategies together. From the sample, I will get an exception for dividing one by zero, but handled by the exception handling strategy.

I hope this entry has given you some good ideas toward maintaining your code base. Download this sample here.

Share this post :

8 Responses to “Strategy and Decorator Pattern”

  1. Tim Coulter Says:

    Thanks – this is an interesting way of tackling a common problem. In fact, I have been trying to find a similarly efficient technique for swapping the cursor during long-running operations in a WPF app. I posted a S.O. question about it here …

    http://stackoverflow.com/questions/3193907/how-to-intercept-execution-of-a-routedcommand-within-the-view-wpf-mvvm

    … but nobody seems to know the answer. Since you’re now also fired up by WPF, do you have any suggestions how to tackle this?

    Thanks,
    Tim

    • Ed Foh Says:

      Hi Tim

      thanks. Very interesting problem, something I expect lots of people would experience.

      Are you using CommandBindings for you routed commands?? I’m just not very sure how you are doing it?

      • Tim Coulter Says:

        Hi Ed,

        Yes, I am using explicitly declared command bindings for the ViewModel classes, implemented via a registration method in a common base class, as described in the following article:

        http://www.codeproject.com/KB/WPF/VMCommanding.aspx

        My app also uses a number of the built-in framework commands to invoke functionality that is restricted to the view layer (e.g applying formatting to a text selection), but I guess I can ignore these, as they tend to execute instantaneously.

      • Ed Foh Says:

        Hi Tim

        Maybe I’m not seeing the whole problem. If you are using command sink and registering you Execute methods in your case class, can’t you just wrap your execute logic with a try..finally block to set your View’s mouse cursor before and after the call. You can wrap those calls using the strategy idea in my post, and that will eliminate your code being duplicated in all your Execute methods.

  2. Ilya Tchivilev Says:

    Nice, I like the chaining – that really makes it a lot better to use.

  3. Tim Says:

    Thank you for sharing but I could not download source files!


Leave a reply to Tim Coulter Cancel reply