Design Patterns: Strategy Pattern


Why

I have used other design patterns such as observer, singleton and memento for some time. I never thought, at least it was never highlighted to me, the use of the Strategy pattern!! Until today!!

No worries

I know it now! And I know how to use it and how useful it is. Today and in the future I'll be using it and now I am just trying to share my knowledge with you...

What is strategy pattern?

The Strategy pattern allows you to define an algorithm separately and select the algorithm dynamically at run time. That's all about strategy pattern and it's really really useful.

How?

That's what is so great about the strategy pattern; the problem is how we can achieve this.

Let's take the simplest example.

Suppose we have a superclass called "Man" and we have extending classes "SuperMan" and "IronMan". See the implementation of the Man class.

PS: PLEASE READ THE COMMENTS ON EACH STEP

abstract class Man
{
  /* Every man can talk */
  void Talk() { }
  /* Every man can walk */
  void Walk() { }
  /* Can every man Fly??? SuperMan can fly, IronMan fly in a different way!! */
  void Fly() { }
}

So we can't implement Fly in the Man class. We have to take it out. Then what might be the solution?

Solution

Implement "Fly" inside the Superman and Ironman separately by taking it out of the Man class

Problem

What about another man which can fly, Let's say "XMan" - he also can fly with rocket engines, which means we have to implement the same fly method inside XMan in a different way. Well there are two places already. So later comes another man who can fly, are we going to implement it in that class as well!! Where are we going to stop?

Another Solution

Implement Fly in an interface and let each candidate implement it.

Problem

We still have the same problem as above, isn't it...

Piece of cake

Let's have a piece of cake.

How about this implementation (this is the piece of cake I told you - just kidding..: P)

namespace Strategy_Pattern
{
    abstract class Man
    {
        /* Add refrences to Flying */
        public IFlying dynamicfly;
 
        /* Every man can talk */
        void Talk() { }
        /* Every man can walk */
        void Walk() { }

        /* Take away Fly from the Man class */
        //void Fly() { } -- DELETE THIS
    }

    /// <summary>
    /// Sub class of Man
    /// </summary>
    class SuperMan : Man
    {
        /* No implementation of Fly Here */
    }

    /// <summary>
    /// Sub class of Man
    /// </summary>
    class IronMan : Man
    {
        /* No implementation of Fly Here */
    }

    /// <summary>
    /// Interface declare the Fly method
    /// </summary>
    interface IFlying
    {
        void Fly();
    }

    /// <summary>
    /// Fly with wings implementation
    /// </summary>
    class FlyWithWings : IFlying
    {
        public void Fly()
        {
            Console.WriteLine("Flying with wings");
        }
    }

    /// <summary>
    /// Fly with rocket implementation
    /// </summary>
    class FlyWithRocket : IFlying
    {
        public void Fly()
        {
            Console.WriteLine("Flying with rocket");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            /* create a superman  */
            SuperMan s = new SuperMan();
            /* We give superman the ability to fly with wings */
            s.dynamicfly = new FlyWithWings();
            /* So superman will fly with wings */
            Console.Write("Call from superman >> ");
            s.dynamicfly.Fly();

            /* Create ironman */
            IronMan i = new IronMan();
            /* We give ironman the ability to fly with rocket */
            i.dynamicfly = new FlyWithRocket();
            /* So ironman will fly with rocket */
            Console.Write("Call from ironman >> ");
            i.dynamicfly.Fly();

            Console.ReadLine();
        }
    }
}


Output

StrPtrn.gif

So we do have Superman who can fly with wings and Ironman who can fly with a rocket and no matter in future if abcman man came with another flying concept ... Then all we have to do is implement that algorithm by implementing the Iflying interface. Isn't it cool?