RSS

GoF – Patrones de diseño (V): Factory Method

18 Mar

El siguiente de los patrones que vamos a revisar es el de “Factory Method”. En este caso, como podéis ver, el nombre es bastante similar a uno de los patrones ya vistos en esta serie de artículos, este sería el “Abstract Factory”. A parte del nombre, existen entre ambos patrones varias similitudes más, de hecho, se puede considerar que el patrón “Factor Method” es una simplificación del patrón de “Abstract Factory”. En mi caso concreto, hasta empezar a leer el libro, no hacía ninguna distinción entre uno y otro, para mi eran algo así como: una factoría compleja (Abstract Factory), y una factoría simple (Factory Method). Y es aquí donde vemos un nuevo ejemplo de la importancia en muchas ocasiones de saber como llamar  de forma correcta aquello que sabemos.

Sin más rodeos, vamos a empezar.

El patrón “Factory Method” se define como una interfaz para la creación de cierto tipo de objeto, permitiendo que las subclases decidan que clase concreta necesitan instanciar. El problema que se plantea en algunos entornos es que una clase no puede anticipar el tipo de objetos que debe crear debido a la jerarquía de clases existente, lo cual provoca que tenga que delegar esta tarea en una subclase.

Por decir lo de una forma menos intrincada, viene a solucionar el problema que se presenta cuando tenemos que crear la instancia de un objeto pero a priori no sabemos aún que tipo de objeto tiene que ser, generalmente, porque depende de alguna opción que seleccione el usuario en la aplicación o porque depende de una configuración que se hace en tiempo de despliegue de la aplicación.

Este patrón se compone de:

  • Product: Define la interfaz de los objetos que de van a crear.
  • ConcreteProduct: Implementación de la interfaz.
  • Creator: Declara la factoría y devuelve un objeto del tipo producto. Además, puede definir una implementación por defecto para la factoria que devolvería un objeto ConcreteProduct por defecto.
  • ConcreteCreator: Sobreescribe el método de la factoría para devolver una instancia concreta de un objeto ConcreteProduct.

A la hora de la implementación tenemos varias opciones disponibles:

  1. El Creator es una clase abstracta y no ofrece ningún tipo de implementación para la factoría que declara. (Ejemplo 1)
  2. El Creator es una clase concreta y ofrece una implementación por defecto de la factoría.
  3. La parametrización de la factoría. Donde la factoría recibe un parámetro con el tipo de objeto que tiene que crear. Todos los objetos disponibles tiene que compartir la interfaz Product. (Ejemplo 2)

No teniendo mucho más que describir, vamos a pasar al ejemplo, donde yo creo que entenderemos mejor todo esto. Como tenemos varias formas posibles de implementación y este yo creo que, junto con el patrón Singleton (que ya veremos), es uno de los patrones que más se utilizan en Frameworks y desarrollos, vamos a ver dos ejemplos. El primero de los tipos vistos más arriba y el parametrizado.

Ejemplo 1: Clase abstracta sin implementación por defecto.

Creator:

public abstract class DBManager {
    public abstract DB factoryMethod();
}

ConcreteCreator:

public class MySQLDBManager extends DBManager {
    protected DB factoryMethod() {
        return new MySQLDB();
    }
}
public class OracleDBManager extends DBManager {
    protected DB factoryMethod() {
        return new OracleDB();
    }
}

Product:

public interface DB {
    public void operation();
}

ConcreteProduct:

public class MySQLDB implements DB {
    public void operation() {
        System.out.println(“Soy MySQL”);
    }
}
public class OracleDB implements DB {
    public void operation() {
        System.out.println(“Soy Oracle”);
    }
}

Main:

public class Main {
    public static void main(String[] args) {
        DBManager manager = new MySQLDBManager();
        MySQLDB mysql = manager.factoryMethod();
        mysql.operation();
        manager = new OracleBDManager();
        OracleDB oracle = manager.factoryMethod();
        oracle.operation();
    }
}

Ejemplo 2: Factoría parametrizada.

Creator and ConcreteCreator:

public class DBManager {
    public static DB createDBConnection(String descriptor) {
        if (“Oracle”.equals(descriptor)) {
            return OracleDB();
        } else if (“MySQL”.equals(descriptor)) {
            return MySQLDB();
        } else { … }
    }
}

Product:

public interface DB {
    public void operation();
}

ConcreteProduct:

public class MySQLDB implements DB {
    public void operation(){
        System.out.println(“Soy MySQL”);
    }
}
public class OracleDB implements DB {
    public void operation(){
        System.out.println(“Soy Oracle”);
    }
}

Main:

public class Main {
    public static void main(String[] args) {
        DB dataBase = DBManager. createDBConnection(“MySQL”);
        dataBase.operation();
        dataBase = DBManager. createDBConnection(“Oracle”);
        dataBase.operation();
    }
}

Ya tenemos una más. Espero que hasta aquí esté siendo todo claro. Dentro de poco la siguiente entrega. Nos vemos.

Anuncios
 
4 comentarios

Publicado por en 18 marzo, 2013 en Patrones de diseño(GoF)

 

4 Respuestas a “GoF – Patrones de diseño (V): Factory Method

  1. Bryan Chauca

    1 julio, 2014 at 8:56 pm

    Muchas gracias por plantearlo pero seria bueno que dejases un “ejemplo problema” y como solucionarlo utilizando el patrón.

     
  2. vick

    30 septiembre, 2014 at 10:06 pm

    el ejercicio1 no compila!

     
  3. vick

    30 septiembre, 2014 at 10:12 pm

    en el main debería ser: DBManager manager = new MySQLDBManager();
    MySQLDB mysql = (MySQLDB)manager.factoryMethod();
    mysql.operation();
    manager = new OracleDBManager();
    OracleDB oracle = (OracleDB)manager.factoryMethod();
    oracle.operation();

    y los métodos factory como public… ahí compila.. saludos!

     
  4. Anónimo

    14 abril, 2017 at 4:11 am

    El ejemplo 2 no compila

     

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: