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”; }

        }

    }

}