viernes, 8 de agosto de 2014

La tienda de animales IV

¿Los contactos de la tienda son importantes? 

Patrón Factory Method

Hola de nuevo a todos y todas. En esta cuarta entrada sobre los patrones GOF seguiremos con el patrón Factory Method para implementar la agenda de contactos de la tienda.

Recordemos que nuestra tienda podía tener clientes representados por la clase Customer y proveedores representados por la clase Suplier.

Cada uno de ellos tendrá información específica que no es necesaria en el otro. Por ejemplo, el proveedor tendrá información sobre su compañía o el tipo de descuento que le hace a la tienda en sus productos.

El diagrama de clases es el que aparece a continuación:



Implementación

El patrón Factory Method tiene una estructura muy sencilla. La clase abstracta Contact es de la que heredan las clases Customer y Suplier que representan a los clientes y los proveedores. En esta hay un método abstracto que se encarga de formar el contenido de cada clase llamando a las clases de Data adecuadas según sea el tipo de Contact.

El código queda así:

public abstract class Contact
{
  List<Data> _datas = new List();

  public List<Data> Datas
  {
    get { return _datas; }
  }

  public Contact()
  {
    this.CreateData();
  }

  public abstract void CreateData();

  public void Show()
  {
    Console.WriteLine(">> " + GetType().Name);

    foreach (var item in _datas)
    {
       Console.WriteLine("\t- " +      item.GetType().Name);
    }
  }
}

public class Customer : Contact
{
  public override void CreateData()
  {
    Datas.Add(new PersonalData());
    Datas.Add(new SalesData());
  }
}

public class Supplier : Contact
{
  public override void CreateData()
  {
    Datas.Add(new CompanyData());
    Datas.Add(new DiscountData());
  }
}

Se puede ver una lista de Data en la clase Contact en la que se almacena la información de cada contacto. Con el método CreateData() se añaden objetos del tipo Data adecuados a la clase Contact correspondiente.

Lo bueno de esto es que si más adelante queremos crear otro tipo de Data sólo habría que hacer un Add en el métdo CreateData() de la subclase de Contact que esté relacionada.
Por ejemplo, si necestamos añadir información sobre las redes sociales que utiliza el contacto usualmente sólo habría que crear una clase que herede de Data y con los campos específicos.
Después en la clase Suplier habría que incluir en el método CreateData() un nuevo Add llamando al constructor de la nueva subclase de Data creada.
Por lo que se refiere a la clase abstracta Data por motivos de simplicidad no se han añadido campos y tampoco en sus subclases. Lo importante aquí es la herencia que se produce entre ellas. De esta forma podemos tener la lista de Data en cada subclase de Contact sin especificar el subtipo instanciado realmente.

public abstract class Data { }

public class SalesData : Data { }

public class CompanyData : Data { }

public class PersonalData : Data { }

public class DiscountData : Data { }

En resumen, hemos visto cómo podemos tener colecciones de objetos que amplian las propiedades de un objeto concreto de forma que estemos preparados ante futuros cambios del modelo sin afectar demasiado a nuestra implementación. Sólo hay que tocar un método añadiendo tantas lineas Add como nuevos subtipos de Data hayamos creado.

Un ejemplo de uso de este patrón en el cliente se resumiría a crear objetos de los subtipos de contact. En el codigo de ejemplo siguiente se utiliza un array como almacén de los Contact.

// Factory Method
Contact[] contacts = new Contact[2];

contacts[0] = new Customer();
contacts[1] = new Supplier();

contacts[0].Show();
contacts[1].Show();


Y esto es todo por ahora. En la próxima entrega hablaremos de los patrones Estructurales y mostraremos el siguiente módulo de la tienda de animales que utilizará estos patrones.

Hasta pronto.




No hay comentarios:

Publicar un comentario