informaticaPC

Patrones de Diseño Software


Regístrate

Tus datos no serán compartidos, solo nosotros te enviaremos información y novedades

Abstract Factory

Este patrón resulta útil en casos en los que necesitemos crear familias de objetos relacionados o dependientes entre sí, sin especificar sus clases concretas. Observa su diagrama en UML:

Patrón Abstract Factory en UM

A continuación mostramos un ejemplo en el que suponiendo que disponemos de dos familias de componentes (compuestas cada una por botones y listas) diferenciadas por el color del borde de los mismos (azul y rojo respectivamente), utilizamos este patrón para insertar primero los pertenecientes a una familia y después los de la otra.

Main.java:

package AbstractFactory;

public class Main
{
    public static void main(String[] args)
    {
        // Se insertarán los componentes con el borde azul
        Cliente cliente = new Cliente( new ComponentesAzules() );

        System.out.println("----------------------------");

        // Ahora se insertarán los componentes con el borde rojo
        cliente = new Cliente( new ComponentesRojos() );
    }
}

Cliente.java:

package AbstractFactory;

public class Cliente
{
    public Cliente( Componentes style )
    {
        Boton boton = style.getBoton();
        boton.dibujar();

        Lista lista = style.getLista();
        lista.dibujar();
    }
}

Componentes.java (una FabricaAbstracta según el diagrama anterior):

package AbstractFactory;

public interface Componentes
{
    public abstract Boton getBoton();
    public abstract Lista getLista();
}

ComponentesAzules.java (una FabricaConcreta según el diagrama anterior):

package AbstractFactory;

public class ComponentesAzules implements Componentes
{
    public ComponentesAzules() {
    }

    // -------------------------------

    public Boton getBoton() {
        return new BotonAzul();
    }

    // -------------------------------

    public Lista getLista() {
        return new ListaAzul();
    }
}

ComponentesRojos.java (una FabricaConcreta según el diagrama anterior):

package AbstractFactory;

public class ComponentesRojos implements Componentes
{
    public ComponentesRojos() {
    }

    // -------------------------------

    public Boton getBoton() {
        return new BotonRojo();
    }

    // -----------------------

    public Lista getLista() {
        return new ListaRoja();
    }
}

Boton.java (un ProductoAbstracto en el diagrama anterior):

package AbstractFactory;

public abstract class Boton
{
    private String texto;

    // -------------------------------

    public String getTexto() {
        return this.texto;
    }

    // -------------------------------

    public void setTexto(String texto) {
        this.texto = texto;
    }

    // -------------------------------

    public void dibujar()
    {
        System.out.println("Dibujando el botón...");
    }

    // -------------------------------

    // Método a implementar por las clases que hereden
    public abstract void configurar();
}

BotonAzul.java (clase que hereda de un ProductoAbstracto, según el diagrama anterior):

package AbstractFactory;

public class BotonAzul extends Boton
{
    public BotonAzul()
    {
        this.configurar();
    }

    // ------------------------------

    public void configurar()
    {
        System.out.println("Configurando el BOTÓN con borde AZUL");
    }
}

BotonRojo.java: (clase que hereda de un ProductoAbstracto, según el diagrama anterior)

package AbstractFactory;

public class BotonRojo extends Boton
{
    public BotonRojo()
    {
        this.configurar();
    }

    // ------------------------------

    public void configurar()
    {
        System.out.println("Configurando el BOTÓN con borde ROJO");
    }
}

Lista.java (un ProductoAbstracto en el diagrama anterior):

package AbstractFactory;

import java.util.ArrayList;

public abstract class Lista
{
    private ArrayList<String> elementos = new ArrayList();

    // -------------------------------

    public String getElemento( int posicion ) {
        return this.elementos.get( posicion );
    }

    // -------------------------------

    public void insertarElemento( String texto ) {
        this.elementos.add( texto );
    }

    // -------------------------------

    public void dibujar()
    {
        System.out.println("Dibujando la lista...");
    }

    // -------------------------------

    // Método a implementar por las clases que hereden
    public abstract void configurar();
}

ListaAzul.java: (clase que hereda de un ProductoAbstracto, según el diagrama anterior)

package AbstractFactory;

public class ListaAzul extends Lista
{
    public ListaAzul()
    {
        this.configurar();
    }

    // ------------------------------

    public void configurar()
    {
        System.out.println("Configurando la LISTA con borde AZUL");
    }
}

ListaRoja.java: (clase que hereda de un ProductoAbstracto, según el diagrama anterior)

package AbstractFactory;

public class ListaRoja extends Lista
{
    public ListaRoja()
    {
        this.configurar();
    }

    // ------------------------------

    public void configurar()
    {
        System.out.println("Configurando la LISTA con borde ROJO");
    }
}

Al ejecutarlo obtendremos el siguiente resultado:

Ejemplo

EXPLICACIÓN:

  • En el programa principal creamos instancias de la clase Cliente, que se encarga de obtener los componentes de la familia indicada y dibujarlos.
  • La interface Componentes (la FabricaAbstracta) define los métodos que deberán tener las clases que la implementen (de tipo FabricaConcreta), mediante los cuales devolverán los componentes solicitados en cada caso.
  • Asimismo las clases abstractas Boton y Lista (de tipo ProductoAbstracto) aparte de implementar métodos comunes, definen otro método que deberán implementar las clases que hereden de ellas (será en el que aplicaremos las diferencias entre los componentes de ambas familias).
Primera página Anterior Siguiente Última página
Usamos cookies para ofrecerte una experiencia mejorada, el continuar navegando supone que aceptas su uso