Factory Method – Serie de patrones de diseño en Java

Factory Method Java

Después de haber visto el patrón de diseño Singleton y Prototype, hoy toca hablar sobre Factory Method, este método es un poco más complejo de desarrollar y entender, pero con la práctica y esta explicación, verás que no será tan complicado.

Qué es el patrón Factory Method?

El patrón Factory Method es como una receta general para crear objetos, donde las subclases son las que deciden qué tipo específico de objeto se debe hacer, según las necesidades del momento. Es una forma de delegar esa decisión para mantener el código más flexible y organizado.

Esto es útil para hacer cosas como:

  • Promover la extensibilidad: Permite agregar nuevas clases sin modificar el código base existente.
  • Reducir el acoplamiento: Evita depender de implementaciones concretas en el código cliente.

Cuando y donde usar Factory Method

Este método es especialmente útil cuando tenemos una base pero requerimos usar multiples comportamientos para cumplir un ciclo de ejecución, esto lo podemos ver en procesos como:

  • Clases con múltiples subtipos: Cuando necesitas crear objetos de diferentes subclases dependiendo del contexto.
  • Desacoplar la lógica de creación: Si no quieres que el cliente (quien usa el objeto) tenga que conocer las implementaciones concretas.
  • Aplicaciones extensibles: Si planeas agregar nuevos tipos de objetos en el futuro sin cambiar el código base.

Y se puede aplicar en casos de uso como:

  • Procesadores de pagos: Crear instancias específicas como Paypal, Stripe o Visa dependiendo del método de pago, mantenemos un proceso de pago pero usamos distintos APIs para pagar.
  • Gestión de notificaciones: Generar notificaciones por SMS, correo electrónico o push según el canal preferido, se mantiene el proceso de notificaciones pero se usan distintos canales.
  • Juegos: Crear diferentes personajes o enemigos según el nivel o escenario, tenemos la base de un NPC por ejemplo pero hará diferentes patrones o dinámicas.
  • Frameworks de UI: Generar botones, ventanas o menús específicos para sistemas operativos diferentes.
  • Acceso a bases de datos: Elegir entre diferentes conexiones a bases de datos como Oracle, MySQL, PostgreSQL o SQL Server dinámicamente.

Cómo implementar Factory Method en Java

Vamos a implementar un servicio de transporte que requiera usar varios tipos de transporte como ejemplo.

1. Interfaz o clase abstracta para el producto

El Factory Method se basa en clases base con métodos de creación abstractos y subclases que proporcionan implementaciones concretas.

Primero se define una interfaz común para los objetos que serán creados:

public interface Transporte {
    void entregar();
}

2. Implementaciones concretas del producto

Ahora definimos las clases que implementan la interfaz o heredan de la clase base.

public class Camion implements Transporte {
    @Override
    public void entregar() {
        System.out.println("Entrega por tierra en un camión.");
    }
}

public class Barco implements Transporte {
    @Override
    public void entregar() {
        System.out.println("Entrega por mar en un barco.");
    }
}

3. Clase creadora base

Se define el método abstracto crearTransporte() que será implementado por las subclases.

public abstract class Logistica {
    public abstract Transporte crearTransporte();

    public void planEntrega() {
        Transporte transporte = crearTransporte();
        transporte.entregar();
    }
}

4. Subclases concretas del creador

Implementamos el método crearTransporte() para devolver instancias específicas.

public class LogisticaTerrestre extends Logistica {
    @Override
    public Transporte crearTransporte() {
        return new Camion();
    }
}

public class LogisticaMaritima extends Logistica {
    @Override
    public Transporte crearTransporte() {
        return new Barco();
    }
}

5. Uso del patrón Factory Method

El cliente utiliza la clase base sin preocuparse por los detalles de las implementaciones concretas.

public class Main {
    public static void main(String[] args) {
        Logistica logisticaTerrestre = new LogisticaTerrestre();
        logisticaTerrestre.planEntrega();

        Logistica logisticaMaritima = new LogisticaMaritima();
        logisticaMaritima.planEntrega();
    }
}

Salida esperada:

Entrega por tierra en un camión.  
Entrega por mar en un barco.  

Ventajas y desventajas del patrón Factory Method

Ventajas:

  1. Desacoplamiento: El cliente no necesita conocer las implementaciones concretas de los objetos.
  2. Extensibilidad: Es fácil agregar nuevos productos sin modificar el código existente.
  3. Centralización de la lógica de creación: Simplifica el mantenimiento del código.

Desventajas:

  1. Mayor complejidad: Puede requerir más clases y métodos, especialmente en proyectos pequeños.
  2. Sobrecarga inicial: Al principio, puede parecer excesivo si solo necesitas crear un objeto sencillo.

Fusionando patrones

Ahora bien, de qué manera podríamos usar Singleton, Prototype y ahora Factory Method??

Todos ellos se pueden implementar por ejemplo en un sistema de gestión de pedidos esto lo podríamos hacer delegando las siguientes tareas a cada patrón:

  • Singleton: Manejaría la configuración global del sistema, como datos de conexión a la base de datos, sesiones de usuarios o configuración de APIs de terceros.
  • Prototype: Clonaría plantillas de productos para crear versiones personalizadas en cada pedido, como categorías o productos con variaciones en tamaño, color, marca, etc.
  • Factory Method: Crearía instancias específicas de pedidos según el tipo (por ejemplo, pedido nacional, internacional, prioritario) junto a los distintos medios de transporte.

Este diseño combina la eficiencia, la flexibilidad y el orden, lo que lo hace ideal para sistemas complejos con múltiples tipos de objetos y configuraciones.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *