1. 程式人生 > >Abstract Factory(C#)

Abstract Factory(C#)

               

Definition

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Participants

The classes and/or objects participating in this pattern are:

  • AbstractFactory (ContinentFactory)
    • Declares an interface for operations that create abstract products
  • ConcreteFactory
     (AfricaFactory, AmericaFactory)
    • Implements the operations to create concrete product objects
  • AbstractProduct (Herbivore, Carnivore)
    • Declares an interface for a type of product object
  • Product (Wildebeest, Lion, Bison, Wolf)
    • Defines a product object to be created by the corresponding concrete factory
    • Implements the AbstractProduct interface
  • Client (AnimalWorld)
    • Uses interfaces declared by AbstractFactory and AbstractProduct classes

Sample Code in C#

This structural code demonstrates the Abstract Factory pattern creating parallel hierarchies of objects. Object creation has been abstracted and there is no need for hard-coded class names in the client code.

// --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Structural Abstract Factory Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{    using System;    /// <summary>    /// Startup class for Structural Abstract Factory Design Pattern.    /// </summary>    internal static class MainApp    {        #region Public Methods and Operators        /// <summary>        /// Entry point into console application.        /// </summary>        public static void Main()        {            // Abstract factory #1            AbstractFactory factory1 = new ConcreteFactory1();            var client1 = new Client(factory1);            client1.Run();            // Abstract factory #2            AbstractFactory factory2 = new ConcreteFactory2();            var client2 = new Client(factory2);            client2.Run();        }        #endregion    }    /// <summary>    /// The 'AbstractFactory' abstract class    /// </summary>    internal abstract class AbstractFactory    {        #region Public Methods and Operators        /// <summary>        /// The create product a.        /// </summary>        /// <returns>        /// The <see cref="AbstractProductA"/>.        /// </returns>        public abstract AbstractProductA CreateProductA();        /// <summary>        /// The create product b.        /// </summary>        /// <returns>        /// The <see cref="AbstractProductB"/>.        /// </returns>        public abstract AbstractProductB CreateProductB();        #endregion    }    /// <summary>    /// The 'ConcreteFactory1' class    /// </summary>    internal class ConcreteFactory1 : AbstractFactory    {        #region Public Methods and Operators        /// <summary>        /// The create product a.        /// </summary>        /// <returns>        /// The <see cref="AbstractProductA"/>.        /// </returns>        public override AbstractProductA CreateProductA()        {            return new ProductA1();        }        /// <summary>        /// The create product b.        /// </summary>        /// <returns>        /// The <see cref="AbstractProductB"/>.        /// </returns>        public override AbstractProductB CreateProductB()        {            return new ProductB1();        }        #endregion    }    /// <summary>    /// The 'ConcreteFactory2' class    /// </summary>    internal class ConcreteFactory2 : AbstractFactory    {        #region Public Methods and Operators        /// <summary>        /// The create product a.        /// </summary>        /// <returns>        /// The <see cref="AbstractProductA"/>.        /// </returns>        public override AbstractProductA CreateProductA()        {            return new ProductA2();        }        /// <summary>        /// The create product b.        /// </summary>        /// <returns>        /// The <see cref="AbstractProductB"/>.        /// </returns>        public override AbstractProductB CreateProductB()        {            return new ProductB2();        }        #endregion    }    /// <summary>    /// The 'AbstractProductA' abstract class    /// </summary>    internal abstract class AbstractProductA    {    }    /// <summary>    /// The 'AbstractProductB' abstract class    /// </summary>    internal abstract class AbstractProductB    {        #region Public Methods and Operators        /// <summary>        /// The interact.        /// </summary>        /// <param name="a">        /// The a.        /// </param>        public abstract void Interact(AbstractProductA a);        #endregion    }    /// <summary>    /// The 'ProductA1' class    /// </summary>    internal class ProductA1 : AbstractProductA    {    }    /// <summary>    /// The 'ProductB1' class    /// </summary>    internal class ProductB1 : AbstractProductB    {        #region Public Methods and Operators        /// <summary>        /// The interact.        /// </summary>        /// <param name="a">        /// The a.        /// </param>        public override void Interact(AbstractProductA a)        {            Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name);        }        #endregion    }    /// <summary>    /// The 'ProductA2' class    /// </summary>    internal class ProductA2 : AbstractProductA    {    }    /// <summary>    /// The 'ProductB2' class    /// </summary>    internal class ProductB2 : AbstractProductB    {        #region Public Methods and Operators        /// <summary>        /// The interact.        /// </summary>        /// <param name="a">        /// The a.        /// </param>        public override void Interact(AbstractProductA a)        {            Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name);        }        #endregion    }    /// <summary>    /// The 'Client' class. Interaction environment for the products.    /// </summary>    internal class Client    {        #region Fields        /// <summary>        /// The abstract product a.        /// </summary>        private AbstractProductA abstractProductA;        /// <summary>        /// The abstract product b.        /// </summary>        private AbstractProductB abstractProductB;        #endregion        // Constructor        #region Constructors and Destructors        /// <summary>        /// Initializes a new instance of the <see cref="Client"/> class.        /// </summary>        /// <param name="factory">        /// The factory.        /// </param>        public Client(AbstractFactory factory)        {            this.abstractProductA = factory.CreateProductA();            this.abstractProductB = factory.CreateProductB();        }        #endregion        #region Public Methods and Operators        /// <summary>        /// The run.        /// </summary>        public void Run()        {            this.abstractProductB.Interact(this.abstractProductA);        }        #endregion    }}// Output:/*ProductB1 interacts with ProductA1ProductB2 interacts with ProductA2*/

This real-world code demonstrates the creation of different animal worlds for a computer game using different factories. Although the animals created by the Continent factories are different, the interactions among the animals remain the same.

// --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Real-World Abstract Factory Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{    using System;    /// <summary>    /// Startup class for Real-World Abstract Factory Design Pattern.    /// </summary>    internal static class MainApp    {        #region Public Methods and Operators        /// <summary>        /// Entry point into console application.        /// </summary>        public static void Main()        {            // Create and run the African animal world            ContinentFactory africa = new AfricaFactory();            var world = new AnimalWorld(africa);            world.RunFoodChain();            // Create and run the American animal world            ContinentFactory america = new AmericaFactory();            world = new AnimalWorld(america);            world.RunFoodChain();        }        #endregion    }    /// <summary>    /// The 'AbstractFactory' abstract class    /// </summary>    internal abstract class ContinentFactory    {        #region Public Methods and Operators        /// <summary>        /// The create carnivore.        /// </summary>        /// <returns>        /// The <see cref="Carnivore"/>.        /// </returns>        public abstract Carnivore CreateCarnivore();        /// <summary>        /// The create herbivore.        /// </summary>        /// <returns>        /// The <see cref="Herbivore"/>.        /// </returns>        public abstract Herbivore CreateHerbivore();        #endregion    }    /// <summary>    /// The 'ConcreteFactory1' class    /// </summary>    internal class AfricaFactory : ContinentFactory    {        #region Public Methods and Operators        /// <summary>        /// The create carnivore.        /// </summary>        /// <returns>        /// The <see cref="Carnivore"/>.        /// </returns>        public override Carnivore CreateCarnivore()        {            return new Lion();        }        /// <summary>        /// The create herbivore.        /// </summary>        /// <returns>        /// The <see cref="Herbivore"/>.        /// </returns>        public override Herbivore CreateHerbivore()        {            return new Wildebeest();        }        #endregion    }    /// <summary>    /// The 'ConcreteFactory2' class    /// </summary>    internal class AmericaFactory : ContinentFactory    {        #region Public Methods and Operators        /// <summary>        /// The create carnivore.        /// </summary>        /// <returns>        /// The <see cref="Carnivore"/>.        /// </returns>        public override Carnivore CreateCarnivore()        {            return new Wolf();        }        /// <summary>        /// The create herbivore.        /// </summary>        /// <returns>        /// The <see cref="Herbivore"/>.        /// </returns>        public override Herbivore CreateHerbivore()        {            return new Bison();        }        #endregion    }    /// <summary>    /// The 'AbstractProductA' abstract class    /// </summary>    internal abstract class Herbivore    {    }    /// <summary>    /// The 'AbstractProductB' abstract class    /// </summary>    internal abstract class Carnivore    {        #region Public Methods and Operators        /// <summary>        /// The eat.        /// </summary>        /// <param name="h">        /// The h.        /// </param>        public abstract void Eat(Herbivore h);        #endregion    }    /// <summary>    /// The 'ProductA1' class    /// </summary>    internal class Wildebeest : Herbivore    {    }    /// <summary>    /// The 'ProductB1' class    /// </summary>    internal class Lion : Carnivore    {        #region Public Methods and Operators        /// <summary>        /// The eat.        /// </summary>        /// <param name="h">        /// The h.        /// </param>        public override void Eat(Herbivore h)        {            // Eat Wildebeest            Console.WriteLine(this.GetType().Name + " eats " + h.GetType().Name);        }        #endregion    }    /// <summary>    /// The 'ProductA2' class    /// </summary>    internal class Bison : Herbivore    {    }    /// <summary>    /// The 'ProductB2' class    /// </summary>    internal class Wolf : Carnivore    {        #region Public Methods and Operators        /// <summary>        /// The eat.        /// </summary>        /// <param name="h">        /// The h.        /// </param>        public override void Eat(Herbivore h)        {            // Eat Bison            Console.WriteLine(this.GetType().Name + " eats " + h.GetType().Name);        }        #endregion    }    /// <summary>    /// The 'Client' class    /// </summary>    internal class AnimalWorld    {        #region Fields        /// <summary>        /// The carnivore.        /// </summary>        private Carnivore carnivore;        /// <summary>        /// The herbivore.        /// </summary>        private Herbivore herbivore;        #endregion        // Constructor        #region Constructors and Destructors        /// <summary>        /// Initializes a new instance of the <see cref="AnimalWorld"/> class.        /// </summary>        /// <param name="factory">        /// The factory.        /// </param>        public AnimalWorld(ContinentFactory factory)        {            this.carnivore = factory.CreateCarnivore();            this.herbivore = factory.CreateHerbivore();        }        #endregion        #region Public Methods and Operators        /// <summary>        /// The run food chain.        /// </summary>        public void RunFoodChain()        {            this.carnivore.Eat(this.herbivore);        }        #endregion    }}// Output:/*Lion eats WildebeestWolf eats Bison*/