Patrones de Diseño (II): Patrones de Creación - Factoría Abstracta

Los patrones de creación se dividen en 2 grupos fundamentales:

  • De clase: Emplea la herencia para variar la clase del objeto creado.
    • Patrones: Factoría Abstracta y Constructor.
  • De objeto: La creación es realizada por otro objeto (delegación).
    • Patrones: Método Factoría, Prototipo y Singleton.


En este artículo definiremos el primer tipo de los Patrones de Creación de Clase, la Factoría Abstracta, siguiendo el esquema general que vimos en la entrega anterior.

Factoría Abstracta


Nombre: Abstract Factory

Problema y Contexto:

Crear diferentes familias de objetos abstrayéndonos de los detalles de su creación.

Se aplica cuando:

  • Hay previsión de que se incluirán nuevas familias de objetos.
  • Existe dependencia (teórica) entre los tipos de objetos.

Solución y Estructura:

La solución será elaborar una interfaz para crear familias de objetos relacionados sin especificar sus clases concretas.

La estructura es la siguiente:

factoría abstracta

Donde:

Cliente: Es el usuario de la factoría, y deberá elegir la factoría adecuada, es decir, lo que quiere es obtener una instancia de alguno de los productos (ProductoA, ProductoB).

AbstractFactory: Define las interfaces de las factorías, provee un método para la obtención de cada objeto que pueda crear (crearProductoA() y crearProductoB())

Factorías Concretas: Representan las diferentes familias de productos, proveen la instancia concreta que se encarga de crear.

Producto abstracto: Interfaz para productos genéricos. En el diagrama son ProductoA y ProductoB. El cliente trabaja directamente con esta interfaz, que será implementada por los diferentes productos concretos.

Producto concreto: Implementación específica de los diferentes productos.

Consecuencias:

  • POSITIVAS:
    • Flexibilidad al aislar las clases concretas.
  • NEGATIVAS:
    • Para añadir nuevas familias hay que modificar tanto las clases abstractas como las concretas.


Patrones Relacionados: Método Factoría (Factory Method)

Ejemplo:

Para entender todo esto mejor, trataremos un caso práctico en Java mediante un ejemplo. En el mismo, crearemos distintos tipos de coches (berlina, coupé y monovolumen) utilizando una Factoría Abstracta.

En primer lugar, partimos de una interfaz Coche que representará a cualquier tipo de coche y definirá las operaciones que cualquier coche puede realizar:


public interface Coche
{
public float getVelocidad();
public String getTipo();

public boolean arrancar();
public int incrementarMarcha();
public int decrementarMarcha();
public float acelerar();
public float frenar();
public void encenderLuces();
public void apagarLuces();
}



Cada vehículo concreto (berlina, coupé y monovolúmen) implementará esta interfaz. La implementación individual de cada tipo no es relevante para el ejemplo.

A continuación crearemos una interfaz Fabricante, que permitirá crear vehículos a toda clase que la implemente:


public interface Fabricante
{
public Coche crearCoche();
}



El siguiente paso es definir las fábricas. Dispondremos de una fábrica principal (la factoría abstracta) que se encargará de invocar a las fábricas concretas de cada tipo de vehículo. Evidentemente tendremos que definir dichas fábricas concretas que implementarán la clase Fabricante:



public class FabricaBerlinas implements Fabricante
{
public Coche crearCoche()
{
Berlina coche_berlina = new Berlina();
return coche_berlina;
}
}

public class FabricaCoupes implements Fabricante
{
public Coche crearCoche()
{
Coupe coche_coupe = new Coupe();
return coche_coupe;
}
}


public class FabricaMonovolumenes implements Fabricante
{
public Coche crearCoche()
{
Monovolumen coche_monovolumen = new Monovolumen();
return coche_monovolumen;
}
}

public class FactoriaAbstractaDeCoches
{
Fabricante fab;
public FactoriaAbstractaDeVehiculos(Fabricante fab)
{
this.fab=fab;
}

public void setFabrica(Fabricante fab)
{
this.fab=fab;
}

public Coche crearCoche()
{
return this.fab.crearCoche();
}
}



Bien, ya tenemos todos los elementos necesarios. Ahora vamos a proceder a utilizarlos en el main:


public static void main(String[] args)
{
FactoriaAbstractaDeCoches f;
Coche miCoche;
if(args[0].equals(“Berlina”))
{
f = new FactoriaAbstractaDeCoches(new FabricaBerlinas());
}
else if(args[0].equals(“Coupe”))
{
f = new FactoriaAbstractaDeCoches(new FabricaCoupes());
}
else if(args[0].equals(“Mono”))
{
f = new FactoriaAbstractaDeCoches(new FabricaMonovolumenes());
}

miCoche = f.crearCoche();
System.out.println(“Tengo un cohe tipo : ”+miCoche.getTipo());
}

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP