CodeGym /Blog Java /Random-ES /patrón de diseño de fábrica
Autor
Andrey Gorkovenko
Frontend Engineer at NFON AG

patrón de diseño de fábrica

Publicado en el grupo Random-ES
¡Hola amigo! Hoy continuaremos estudiando patrones de diseño. En esta lección, vamos a hablar sobre las fábricas. Discutiremos el problema que resuelve este patrón y veremos un ejemplo de cómo una fábrica puede ayudarlo a abrir una cafetería. Además, te daré 5 pasos simples para crear una fábrica. Patrón de diseño de fábrica - 1 Para asegurarse de que todos estamos en la misma longitud de onda y que comprenderá rápidamente este concepto, debe estar familiarizado con los siguientes temas:
  • Herencia en Java
  • Estrechamiento y ampliación de tipos de referencia en Java
  • Interacción entre diferentes clases y objetos.

¿Qué es una fábrica?

El patrón de diseño de fábrica le permite controlar la creación de objetos. El proceso de creación de un nuevo objeto no es súper simple, pero tampoco demasiado complicado. Todos sabemos que necesitamos el newoperador para crear un nuevo objeto. Quizás parezca que aquí no hay nada que controlar, pero eso no es cierto. Supongamos que nuestra aplicación tiene una cierta clase que tiene muchos descendientes. Pueden surgir dificultades cuando es necesario crear una instancia de una clase específica dependiendo de ciertas condiciones. Una fábrica es un patrón de diseño que ayuda a resolver el problema de crear varios objetos dependiendo de ciertas condiciones. ¿Cómo es eso para un concepto abstracto? Esto se volverá más claro y más específico cuando veamos el siguiente ejemplo.

Preparemos varios tipos de café.

Supongamos que queremos automatizar una cafetería. Necesitamos enseñar a nuestro programa cómo hacer diferentes tipos de café. Para ello, crearemos una clase de café y algunas clases derivadas para representar los tipos de café que prepararemos: americano, capuchino, espresso y latte. Comencemos con una clase general de café:

public class Coffee {
    public void grindCoffee(){
        // Grind the coffee
    }
    public void makeCoffee(){
        // Brew the coffee
    }
    public void pourIntoCup(){
        // Pour into a cup
    }
}
A continuación, crearemos sus clases secundarias:

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Nuestros clientes pueden pedir cualquier tipo de café. Sus órdenes deben pasarse al programa. Esto se puede hacer de muchas maneras, por ejemplo, usando String. Pero un enumes mejor para esto. Crearemos enumy definiremos campos de enumeración que correspondan a los tipos de café que se pueden pedir:

public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
Excelente. Ahora escribamos el código de nuestra cafetería:

public class CoffeeShop {
    
    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = null;
        
        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappucсino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Here's your coffee! Thanks! Come again!");
        return coffee;
    }
}
El orderCoffeemétodo se puede dividir en dos partes:
  1. Creación de una instancia específica de café en una switchdeclaración. Aquí es donde una fábrica hace lo que hace: crear un tipo específico según las condiciones.
  2. Preparación: se trata de moler, preparar y verter en una taza.
Esto es lo que es importante saber si necesita realizar cambios en el método en el futuro:
  1. Los pasos involucrados en la preparación en sí (moler, colar y verter en una taza) permanecerán sin cambios (al menos contamos con esto).
  2. Pero la variedad de cafés puede cambiar. Tal vez empecemos a hacer moka... Frappu... Mochacci... Lo que sea, un nuevo tipo de café.
Ya podemos estar bastante seguros de que en el futuro tendremos que hacer cambios en la switchdeclaración del método. También es posible que en nuestra cafetería el orderCoffeemétodo no sea el único lugar donde crearemos diferentes tipos de café. Como resultado, habrá que hacer cambios en varios lugares. Probablemente ya entiendas a lo que me refiero. Necesitamos refactorizar. Mueva el bloque responsable de crear café a una clase separada por dos razones:
  1. Podemos reutilizar la lógica de hacer café en otros lugares.
  2. Si el surtido cambia, no tendremos que editar el código en todos los lugares donde se crea el café. Bastará con cambiar nuestro código en un solo lugar.
En otras palabras, ha llegado el momento de montar una fábrica.

Montando nuestra primera fábrica

Para ello, crearemos una nueva clase que solo se encargará de crear las instancias necesarias de las clases de café:

public class SimpleCoffeeFactory {
    public Coffee createCoffee(CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappucino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }
        
        return coffee;
    }
}
¡Felicidades! Acabamos de implementar el patrón de diseño de fábrica en su forma más simple (casi). Podría haber sido aún más simple si hubiéramos hecho el createCoffeemétodo estático. Pero entonces perderíamos dos capacidades:
  1. La capacidad de heredar SimpleCoffeeFactoryy anular el createCoffeemétodo.
  2. La capacidad de agregar la implementación de fábrica requerida a nuestras clases.
Por cierto, hablando de implementación... Necesitamos volver a la cafetería y agregar nuestra fábrica de café.

Añadir una fábrica a la cafetería.

Reescribamos la clase de cafetería usando una fábrica:

public class CoffeeShop {

    private final SimpleCoffeeFactory coffeeFactory;

    public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = coffeeFactory.createCoffee(type);
        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Here's your coffee! Thanks! Come again!");
        return coffee;
    }
}
Excelente. Ahora proporcionaremos una descripción concisa de la estructura general del patrón de diseño de fábrica.

5 pasos para abrir tu propia fábrica

Paso 1. Su programa tiene una clase con varios descendientes, como en el siguiente diagrama: Patrón de diseño de fábrica - 2Paso 2. Crea un enumcon un campo para cada clase secundaria:

    enum CatType {
        LION,
        TIGER,
        FLUFFY
    }
Paso 3. Construye tu fábrica. Llámalo CatFactory_ Aquí está el código:

class CatFactory {}
Paso 4. En su fábrica, cree un createCatmétodo que tome un CatTypeargumento. Aquí está el código:

    class CatFactory {
        public Cat createCat(CatType type) {
            
        }
    }
Paso 5. En el cuerpo del método, escriba una switchdeclaración que enumere los campos de enumeración y cree una instancia de la clase que corresponda al enumvalor pasado:

class CatFactory {
        public Cat createCat(CatType type) {
            Cat cat = null;
            
            switch (type) {
                case LION:
                    cat =  new Fluffy();
                    break;
                case TIGER:
                    cat = new Tiger();
                    break;
                case FLUFFY:
                    cat =  new Lion();
                    break;
            }
            
            return cat;
        }
    }
Ahora puedes dirigir una fábrica como un jefe. :)

como practicar

Leer es bueno, escribir código es aún mejor. Si su nombre tiene un número par de letras, intente crear su propia pizzería virtual. Si su nombre tiene un número impar de letras, intente crear una barra de sushi virtual. Si no tienes nombre, tuviste suerte. Hoy puedes relajarte.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION