Strategy design pattern

Strategy

Strategy pattern defines a family of algorithms, encapsulates each one, make them interchangeable. Strategy lets algorithms vary independently from clients that use it.

Strategy

Context is configured with strategy object. Maintains a reference to a strategy object. May defined an interface to access to strategy data.

public class Context<T>
{
	private IAbstractStrategy<T> _strategy;

	private Context(){}

	/// <summary>
	/// A context constructor which takes a concrete class 
	/// which implements algorithms
	/// </summary>
	/// <param name="strategy">A concrete class which implements algorithms to call</param>
	public Context(IAbstractStrategy<T> strategy)
	{
		_strategy = strategy;           
	}

	/// <summary>
	/// A member of the context class which is capable to use members of the concrete strategy class
	/// </summary>
	public T PerformAlgorithm(T param)
	{
		return _strategy.PerformAlgorithm(param);
	}
}

Strategy defines an interface common for all supported algorithms

/// <summary>
/// Defines an interface which have common methods to call by its context class
/// </summary>   
public interface IAbstractStrategy<T>
{
	T PerformAlgorithm(T param);
}

ConcreteStrategy implements the Strategy interface

/// <summary>
/// Concrete class which implements an interface defined by its contract
/// </summary>
public class ConcreteStrategy1<T> : IAbstractStrategy<T>
{
	public T PerformAlgorithm(T param)
	{
		return param;
	}
}

Abstract Factory

Abstract Factory

Provides an interface for creating families of related objects without specifying  their concrete classes. 

Using:

        static void Main(string[] args)

        {

            ShowResult(new ConcreteFactoryA());

            ShowResult(new ConcreteFactoryB());

            Console.ReadKey();

        }

        static void ShowResult(AbstractFactory factory)

        {

            AbstractProduct1 product1 = factory.CreateProduct1();

            AbstractProduct2 product2 = factory.CreateProduct2();

            Trace.WriteLine(product1.GetProduct2Name(product2));

        }

Output:

ConcreteProduct2ForA

ConcreteProduct2ForB

Implementation:

namespace AbstractFactory

{

    /// <summary>

    /// Declares an interface to create an abstract product

    /// </summary>

    public abstract class AbstractFactory

    {

        public abstract AbstractProduct1 CreateProduct1();

        public abstract AbstractProduct2 CreateProduct2();

    }

    /// <summary>

    /// Implements the AbstractFactory interaface to create a concrete product

    /// </summary>

    public class ConcreteFactoryA : AbstractFactory

    {

        public override AbstractProduct1 CreateProduct1()

        {

            return new ConcreteProduct1ForA();

        }

        public override AbstractProduct2 CreateProduct2()

        {

            return new ConcreteProduct2ForA();

        }

    }

    /// <summary>

    /// Implements the AbstractFactory interaface to create a concrete product

    /// </summary>

    public class ConcreteFactoryB : AbstractFactory

    {   

        public override AbstractProduct1 CreateProduct1()

        {

            return new ConcreteProduct1ForB();

        }

        public override AbstractProduct2 CreateProduct2()

        {

            return new ConcreteProduct2ForB();

        }

    }

    /// <summary>

    /// Declares an interface of an abstract product

    /// </summary>

    public abstract class AbstractProduct1

    {

        public abstract string GetProduct2Name(AbstractProduct2 product2);

    }

    /// <summary>

    /// Declares an interface of an abstract product

    /// </summary>

    public abstract class AbstractProduct2

    {

        public abstract string Name { get; }

    }

    /// <summary>

    /// Implements the interface of the corresponded abstract product to be created by the corresponding concrete factory

    /// </summary>

    public class ConcreteProduct1ForA : AbstractProduct1

    {

        public override string GetProduct2Name(AbstractProduct2 product2)

        {

            return product2.Name;

        }

    }

    /// <summary>

    /// Implements the interface of the corresponded abstract product to be created by the corresponding concrete factory

    /// </summary>

    public class ConcreteProduct2ForB : AbstractProduct2

    {

        public override string Name

        {

            get { return “ConcreteProduct2ForB”; }

        }

    }

    /// <summary>

    /// Implements the interface of the corresponded abstract product to be created by the corresponding concrete factory

    /// </summary>

    public class ConcreteProduct1ForB : AbstractProduct1

    {

        public override string GetProduct2Name(AbstractProduct2 product2)

        {

            return product2.Name;

        }

    }

    /// <summary>

    /// Implements the interface of the corresponded abstract product to be created by the corresponding concrete factory

    /// </summary>

    public class ConcreteProduct2ForA : AbstractProduct2

    {

        public override string Name

        {

            get { return “ConcreteProduct2ForA”; }

        }

    }

}