miércoles, 8 de octubre de 2014

Abstract Factory (Fabrica Abstracta) Patron de diseño


Crea una instancia de varias familias de clases

Definición


Proporcionar una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas.


Frecuencia de uso:
High


























UML class diagram


Los participantes


Las clases y los objetos que participan en este modelo son:

  • AbstractFactory (ContinentFactory) 
  1. declara una interfaz para las operaciones que crean productos abstractos 
  • ConcreteFactory (AfricaFactory, AmericaFactory) 
  1. implementa las operaciones para crear objetos de productos concretos 
  • AbstractProduct (Herbivore, Carnivore) 
  1. declara una interfaz para un tipo del objeto Product
  • Product (Wildebeest, Lion, Bison, Wolf) 
  1. define un objeto de producto que se crea por la correspondiente fábrica de hormigón 
  2. implementa la interfaz AbstractProduct 
  • Client (AnimalWorld) 
  1. utiliza interfaces declaradas por las clases AbstractFactory y AbstractProduct 
Código estructural en C # 

Este código estructural demuestra el patrón Abstract Factory crear jerarquías paralelas de los objetos. Creación de objetos ha sido abstraído y no hay necesidad de nombres de clase no modificables en el código de cliente.

  1. using System;

  2. namespace Abstract.Structural
  3. {
  4.   /// <summary>
  5.   /// MainApp startup class for Structural
  6.   /// Abstract Factory Design Pattern.
  7.   /// </summary>
  8.   class MainApp
  9.   {
  10.     /// <summary>
  11.     /// Entry point into console application.
  12.     /// </summary>
  13.     public static void Main()
  14.     {
  15.       // Abstract factory #1
  16.       AbstractFactory factory1 = new ConcreteFactory1();
  17.       Client client1 = new Client(factory1);
  18.       client1.Run();

  19.       // Abstract factory #2
  20.       AbstractFactory factory2 = new ConcreteFactory2();
  21.       Client client2 = new Client(factory2);
  22.       client2.Run();

  23.       // Wait for user input
  24.       Console.ReadKey();
  25.     }
  26.   }

  27.   /// <summary>
  28.   /// The 'AbstractFactory' abstract class
  29.   /// </summary>
  30.   abstract class AbstractFactory
  31.   {
  32.     public abstract AbstractProductA CreateProductA();
  33.     public abstract AbstractProductB CreateProductB();
  34.   }


  35.   /// <summary>
  36.   /// The 'ConcreteFactory1' class
  37.   /// </summary>
  38.   class ConcreteFactory1 : AbstractFactory
  39.   {
  40.     public override AbstractProductA CreateProductA()
  41.     {
  42.       return new ProductA1();
  43.     }
  44.     public override AbstractProductB CreateProductB()
  45.     {
  46.       return new ProductB1();
  47.     }
  48.   }

  49.   /// <summary>
  50.   /// The 'ConcreteFactory2' class
  51.   /// </summary>
  52.   class ConcreteFactory2 : AbstractFactory
  53.   {
  54.     public override AbstractProductA CreateProductA()
  55.     {
  56.       return new ProductA2();
  57.     }
  58.     public override AbstractProductB CreateProductB()
  59.     {
  60.       return new ProductB2();
  61.     }
  62.   }

  63.   /// <summary>
  64.   /// The 'AbstractProductA' abstract class
  65.   /// </summary>
  66.   abstract class AbstractProductA
  67.   {
  68.   }

  69.   /// <summary>
  70.   /// The 'AbstractProductB' abstract class
  71.   /// </summary>
  72.   abstract class AbstractProductB
  73.   {
  74.     public abstract void Interact(AbstractProductA a);
  75.   }


  76.   /// <summary>
  77.   /// The 'ProductA1' class
  78.   /// </summary>
  79.   class ProductA1 : AbstractProductA
  80.   {
  81.   }

  82.   /// <summary>
  83.   /// The 'ProductB1' class
  84.   /// </summary>
  85.   class ProductB1 : AbstractProductB
  86.   {
  87.     public override void Interact(AbstractProductA a)
  88.     {
  89.       Console.WriteLine(this.GetType().Name +
  90.         " interacts with " + a.GetType().Name);
  91.     }
  92.   }

  93.   /// <summary>
  94.   /// The 'ProductA2' class
  95.   /// </summary>
  96.   class ProductA2 : AbstractProductA
  97.   {
  98.   }

  99.   /// <summary>
  100.   /// The 'ProductB2' class
  101.   /// </summary>
  102.   class ProductB2 : AbstractProductB
  103.   {
  104.     public override void Interact(AbstractProductA a)
  105.     {
  106.       Console.WriteLine(this.GetType().Name +
  107.         " interacts with " + a.GetType().Name);
  108.     }
  109.   }

  110.   /// <summary>
  111.   /// The 'Client' class. Interaction environment for the products.
  112.   /// </summary>
  113.   class Client
  114.   {
  115.     private AbstractProductA _abstractProductA;
  116.     private AbstractProductB _abstractProductB;

  117.     // Constructor
  118.     public Client(AbstractFactory factory)
  119.     {
  120.       _abstractProductB = factory.CreateProductB();
  121.       _abstractProductA = factory.CreateProductA();
  122.     }

  123.     public void Run()
  124.     {
  125.       _abstractProductB.Interact(_abstractProductA);
  126.     }
  127.   }
  128. }
Resultado
ProductB1 interacts with ProductA1
ProductB2 interacts with ProductA2

Código del mundo real en C #

Este código del mundo real demuestra la creación de diferentes animales para un juego de ordenador utilizando diferentes fábricas. Aunque los animales creados por las fábricas son de continente diferentes, las interacciones entre los animales siguen siendo los mismos.

  1. using System;

  2. namespace Abstract.RealWorld
  3. {
  4.   /// <summary>
  5.   /// MainApp startup class for Real-World
  6.   /// Abstract Factory Design Pattern.
  7.   /// </summary>
  8.   class MainApp
  9.   {
  10.     /// <summary>
  11.     /// Entry point into console application.
  12.     /// </summary>
  13.     public static void Main()
  14.     {
  15.       // Create and run the African animal world
  16.       ContinentFactory africa = new AfricaFactory();
  17.       AnimalWorld world = new AnimalWorld(africa);
  18.       world.RunFoodChain();

  19.       // Create and run the American animal world
  20.       ContinentFactory america = new AmericaFactory();
  21.       world = new AnimalWorld(america);
  22.       world.RunFoodChain();
  23.       // Wait for user input
  24.       Console.ReadKey();
  25.     }
  26.   }

  27.   /// <summary>
  28.   /// The 'AbstractFactory' abstract class
  29.   /// </summary>
  30.   abstract class ContinentFactory
  31.   {
  32.     public abstract Herbivore CreateHerbivore();
  33.     public abstract Carnivore CreateCarnivore();
  34.   }

  35.   /// <summary>
  36.   /// The 'ConcreteFactory1' class
  37.   /// </summary>
  38.   class AfricaFactory : ContinentFactory
  39.   {
  40.     public override Herbivore CreateHerbivore()
  41.     {
  42.      return new Wildebeest();
  43.     }
  44.     public override Carnivore CreateCarnivore()
  45.     {
  46.       return new Lion();
  47.     }
  48.   }

  49.   /// <summary>
  50.   /// The 'ConcreteFactory2' class
  51.   /// </summary>
  52.   class AmericaFactory : ContinentFactory
  53.   {
  54.     public override Herbivore CreateHerbivore()
  55.     {
  56.       return new Bison();
  57.     }
  58.     public override Carnivore CreateCarnivore()
  59.     {
  60.       return new Wolf();
  61.     }
  62.   }

  63.   /// <summary>
  64.   /// The 'AbstractProductA' abstract class
  65.   /// </summary>
  66.   abstract class Herbivore
  67.   {
  68.   }
  69.   /// <summary>
  70.   /// The 'AbstractProductB' abstract class
  71.   /// </summary>
  72.   abstract class Carnivore
  73.   {
  74.     public abstract void Eat(Herbivore h);
  75.   }
  76.   /// <summary>
  77.   /// The 'ProductA1' class
  78.   /// </summary>
  79.   class Wildebeest : Herbivore
  80.   {
  81.   }

  82.   /// <summary>
  83.   /// The 'ProductB1' class
  84.   /// </summary>
  85.   class Lion : Carnivore
  86.   {
  87.     public override void Eat(Herbivore h)
  88.     {
  89.       // Eat Wildebeest
  90.      Console.WriteLine(this.GetType().Name +
  91.         " eats " + h.GetType().Name);
  92.     }
  93.   }

  94.   /// <summary>
  95.   /// The 'ProductA2' class
  96.   /// </summary>
  97.   class Bison : Herbivore
  98.   {
  99.   }

  100.   /// <summary>
  101.   /// The 'ProductB2' class
  102.   /// </summary>
  103.   class Wolf : Carnivore
  104.   {
  105.     public override void Eat(Herbivore h)
  106.     {
  107.       // Eat Bison
  108.       Console.WriteLine(this.GetType().Name +
  109.         " eats " + h.GetType().Name);
  110.     }
  111.   }
  112.   /// <summary>
  113.   /// The 'Client' class
  114.   /// </summary>
  115.   class AnimalWorld
  116.   {
  117.     private Herbivore _herbivore;
  118.     private Carnivore _carnivore;

  119.     // Constructor
  120.     public AnimalWorld(ContinentFactory factory)
  121.     {
  122.       _carnivore = factory.CreateCarnivore();
  123.       _herbivore = factory.CreateHerbivore();
  124.     }
  125.     public void RunFoodChain()
  126.     {
  127.       _carnivore.Eat(_herbivore);
  128.     }
  129.   }
  130. }

Resultado
Lion eats Wildebeest
Wolf eats Bison