Menu
Coddy logo textTech

Patrón Factory

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 66 de 87.

El Patrón Factory es un patrón de diseño creacional que delega la creación de objetos a un método o clase independiente. En lugar de usar new directamente en tu código, le pides a una fábrica que cree objetos por ti. Esto es especialmente útil cuando tienes múltiples clases relacionadas que comparten una interfaz o padre común.

Considere un sistema de notificaciones que puede enviar correos electrónicos, SMS o notificaciones push. Sin una fábrica, su código necesitaría conocer cada clase concreta:

// Sin Factory - el cliente debe conocer todas las clases concretas
Notification notification;
if (type.equals("email")) {
    notification = new EmailNotification();
} else if (type.equals("sms")) {
    notification = new SMSNotification();
}

Con el Patrón Factory, centralizas esta lógica de creación:

public interface Notification {
    void send(String message);
}

public class EmailNotification implements Notification {
    public void send(String message) {
        System.out.println("Email: " + message);
    }
}

public class SMSNotification implements Notification {
    public void send(String message) {
        System.out.println("SMS: " + message);
    }
}

public class NotificationFactory {
    public static Notification create(String type) {
        if (type.equals("email")) {
            return new EmailNotification();
        } else if (type.equals("sms")) {
            return new SMSNotification();
        }
        return null;
    }
}

Ahora el código del cliente es más limpio y no depende de clases concretas:

Notification notification = NotificationFactory.create("email");
notification.send("Hello!");  // Salida: Email: Hello!

El beneficio clave es que agregar nuevos tipos de notificación solo requiere actualizar la fábrica; el código del cliente permanece sin cambios. Esto sigue el principio de programar para una interfaz, lo que hace que su sistema sea más flexible y fácil de extender.

challenge icon

Desafío

Fácil

¡Vamos a construir un sistema de dibujo de formas utilizando el Patrón Factory! En lugar de crear objetos de forma directamente en todo tu código, centralizarás la lógica de creación en una fábrica que produce diferentes tipos de formas basadas en un identificador de cadena simple.

Organizarás tu código en cuatro archivos:

  • Shape.java: Define una interfaz llamada Shape que sirva como el contrato común para todas las formas. Tu interfaz debe declarar un único método draw() que no devuelva nada pero imprima información sobre la forma que se está dibujando.
  • Shapes.java: Crea tres clases que implementen tu interfaz Shape:

    Circle - su método draw() debe imprimir Drawing a Circle

    Rectangle - su método draw() debe imprimir Drawing a Rectangle

    Triangle - su método draw() debe imprimir Drawing a Triangle

  • ShapeFactory.java: Crea la clase de fábrica que maneja la creación de formas. Tu ShapeFactory debe tener un método estático createShape(String type) que devuelva un Shape. Basado en el parámetro type:
    • Si type es igual a "circle", devuelve un nuevo Circle
    • Si type es igual a "rectangle", devuelve un nuevo Rectangle
    • Si type es igual a "triangle", devuelve un nuevo Triangle
    • Para cualquier otro valor, devuelve null
  • Main.java: ¡Une tu sistema de fábrica! Recibirás dos entradas: dos tipos de formas (ambas Strings).

    Para cada entrada, usa tu ShapeFactory para crear la forma y almacénala en una variable Shape. Si la fábrica devuelve una forma válida (no nula), llama a su método draw(). Si devuelve nulo, imprime Unknown shape: [type] donde [type] es la entrada que se proporcionó.

    Procesa ambas entradas en orden, cada una en su propia línea de salida.

Recibirás dos entradas en orden: el primer tipo de forma (String) y el segundo tipo de forma (String).

Observa cómo tu clase Main nunca usa new Circle() o new Rectangle() directamente; solo conoce la interfaz Shape y le pide a la fábrica que cree los objetos. ¡Este es el poder del Patrón Factory: el código del cliente está desacoplado de las clases concretas!

Hoja de referencia

El Patrón Factory es un patrón de diseño creacional que delega la creación de objetos a un método o clase independiente, centralizando la lógica de creación y desacoplando el código del cliente de las implementaciones concretas.

En lugar de instanciar objetos directamente con new, se utiliza un método de fábrica:

// Sin Factory - el cliente depende de clases concretas
Notification notification;
if (type.equals("email")) {
    notification = new EmailNotification();
} else if (type.equals("sms")) {
    notification = new SMSNotification();
}

Con el Patrón Factory, defina una interfaz común e implementaciones concretas:

public interface Notification {
    void send(String message);
}

public class EmailNotification implements Notification {
    public void send(String message) {
        System.out.println("Email: " + message);
    }
}

public class SMSNotification implements Notification {
    public void send(String message) {
        System.out.println("SMS: " + message);
    }
}

Cree una clase de fábrica con un método de creación estático:

public class NotificationFactory {
    public static Notification create(String type) {
        if (type.equals("email")) {
            return new EmailNotification();
        } else if (type.equals("sms")) {
            return new SMSNotification();
        }
        return null;
    }
}

El código del cliente utiliza la fábrica en lugar de la instanciación directa:

Notification notification = NotificationFactory.create("email");
notification.send("Hello!");  // Salida: Email: Hello!

Beneficios: Agregar nuevos tipos solo requiere actualizar la fábrica; el código del cliente permanece sin cambios. Esto sigue el principio de programar para una interfaz, lo que hace que los sistemas sean más flexibles y fáciles de extender.

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lee dos tipos de formas
        String type1 = scanner.nextLine();
        String type2 = scanner.nextLine();
        
        // TODO: Usa ShapeFactory para crear la primera forma
        // Si la forma no es null, llama a draw()
        // Si la forma es null, imprime "Unknown shape: [type]"
        
        // TODO: Haz lo mismo para la segunda forma
        
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos