Patrones de diseño de creación: Factory Method

Intención del patrón

  • Definir una interfaz para crear un objeto, pero dejar que las subclases decidan cuál clase instanciar. Factory Method permite a una clase diferir la instanciación a subclases.
  • La definición de un constructor "virtual".
  • Que el operador new sea considerado dañino.

Ejemplo de problema
Un framework necesita estandarizar el modelo de arquitectura para una variedad de aplicaciones, pero permitirle las aplicaciones definir de manera individual sus propios objetos de dominio y asegurar su instanciación.

Discusión
Factory Method sirve para crear objetos así como Template Method se utiliza para implementar un algoritmo. Una superclase especifica todos los comportamientos estándares y genéricos (usando "placeholders" puros para los pasos de la creación), y delega los detalles de la creación a las subclases que son suministradas por el cliente.
Factory Method permite un diseño más personalizable y sólo un poco más complicado. Otros patrones de diseño requieren nuevas clases, mientras que éste sólo requiere una nueva operación.
A menudo se usa éste patrón como la manera estándar de crear objetos; pero no sería necesario si: la clase que se instancia nunca cambia, o la instanciación toma lugar en un método que una subclase puede fácilmente sobrescribir (como un método de inicialización).
Éste patrón es similar al patrón Abstract Factory, pero sin el énfasis en las familias de objetos.
Los Factory Methods son especificados de manera rutinaria por un framework arquitectónico, y entonces es implementado por el usuario de dicho framework.
Estructura
La implementación de Factory Method discutida por el GoF, coincide en gran medida con el patrón Abstract Factory. Por esta razón, la presentación en este post se centra en el enfoque que lo ha vuelto popular desde entonces.
Una definición cada vez más popular de éste patrón es: un método static de una clase que retorna un objeto del mismo tipo. Pero a diferencia de un constructor, el objeto real que retorna puede ser la instancia de una subclase. Otra diferencia con un constructor, es que un objeto existente puede ser reutilizado en lugar de crear un nuevo objeto. También, pueden tener nombres diferentes y más descriptivos (Ej. Color.make_RGB_color(float red, float green, float blue) Color.make_HSB_color(float hue, float saturation, float brightness))
El cliente queda totalmente desacoplado de los detalles de la implementación de clases derivadas. La creación polimórfica es ahora posible.
Ejemplo
El patrón Factory Method define una interfaz para la creación de objetos, pero le permite a las subclases decidir cuales clases instanciar. Las prensas de inyección de matrices demuestran este patrón. Los fabricantes de juguetes de plástico procesando el moldeado de polvo de plástico, y lo inyecta en los moldes con la forma deseada. La clase de juguete (Auto, muñeco, etc.) es determinado por el molde.
Check list

  1. Si se tiene una jerarquía de herencia que posee polimorfismo, se debe considerar la capacidad polimórfica de creación mediante la definición de un Factory Method static en la clase base.
  2. Diseñar los argumentos para el Factory Method. ¿Qué cualidades o características son necesarias y suficientes para identificar la clase derivada correcta para instanciar?
  3. Considerar el diseño de un Object Pool interno que permita que los objetos sean reutilizados en lugar de crearlos desde cero.
  4. Considerar que todos los constructores sean private o protected.

Reglas de oro

  • Las Abstract Factory son a menudo implementadas con Factory Methods, pero ellos pueden ser implementados usando Prototype.
  • Los Factory Method suelen ser llamados dentro de los Template Method.
  • Factory Method: creación a través de la herencia. Template Method: creación a través de la delegación.
  • A menudo, el diseño nace como un Factory Method (menos complicado, más personalizable, proliferan las subclases) y evolucionan hacia un Abstract FactoryPrototype Builder (más flexible, más complejo) como el diseñador descubra cuánta flexibilidad es necesaria.
  • Prototype no requiere subclases, pero necesita una operación de inicialización. Factory Method requiere subclases, pero no necesita ser inicializado.
  • La ventaja de un Factory Method es que puede retornar la misma instancia varias veces, o puede retornar una subclase en lugar de un objeto del mismo tipo.
  • Algunos defensores del Factory Method recomiendan como una cuestión del lenguaje de diseño (o en su defecto, como una cuestión de estilo), absolutamente todos los constructores deberían ser private o protected. No es incumbencia de nadie cuándo una clase crea un objeto o si un objeto viejo reciclado.
  • El operador new se considera como algo dañino. Es diferente solicitar un objeto que crear uno. El operador new siempre crea un objeto y falla la encapsulación de la creación del mismo. Un Factory Method fuerza dicha encapsulación y le permite a un objeto ser solicitado evitando el acoplamiento en el acto de la creación del mismo.

Ejemplo de código en C#
using System;
using System.Collections;

class MainApp
{
  static void Main()
  {
    // An array of creators 
    Creator[] creators = new Creator[2];
    creators[0] = new ConcreteCreatorA();
    creators[1] = new ConcreteCreatorB();

    // Iterate over creators and create products 
    foreach(Creator creator in creators)
    {
      Product product = creator.FactoryMethod();
      Console.WriteLine("Created {0}", 
        product.GetType().Name);
    }

    // Wait for user 
    Console.Read();
  }
}

// "Product" 
abstract class Product
{
}

// "ConcreteProductA" 
class ConcreteProductA : Product
{
}

// "ConcreteProductB" 
class ConcreteProductB : Product
{
}

// "Creator" 
abstract class Creator
{
  public abstract Product FactoryMethod();
}

// "ConcreteCreator" 
class ConcreteCreatorA : Creator
{
  public override Product FactoryMethod()
  {
    return new ConcreteProductA();
  }
}

// "ConcreteCreator" 
class ConcreteCreatorB : Creator
{
  public override Product FactoryMethod()
  {
    return new ConcreteProductB();
  }
}

0 comentarios:

Publicar un comentario

Muchas gracias por leer el post y comentarlo.

 
Copyright 2009 Programación SOLIDa
BloggerTheme by BloggerThemes | Design by 9thsphere