JavaRush /Blogue Java /Random-PT /Padrão de design de fábrica

Padrão de design de fábrica

Publicado no grupo Random-PT
Oi amigo! Hoje continuaremos estudando padrões de design com você. Nesta palestra falaremos sobre a Fábrica. Discutiremos com você qual problema é resolvido usando este modelo e veremos um exemplo de como uma fábrica ajuda a abrir uma cafeteria. E também darei 5 passos simples para criar uma fábrica. Padrão de Design de Fábrica - 1Para estar na mesma página com todos e compreender facilmente a essência, você deve estar familiarizado com os seguintes tópicos:
  • Herança em Java
  • Estreitando e expandindo tipos de referência em Java
  • Interação entre diferentes classes e objetos

O que é uma fábrica?

O padrão de design Factory permite controlar a criação de objetos. O processo de criação de um novo objeto não é tão simples, mas também não é muito complicado. Todos sabemos que para criar um novo objeto devemos usar o arquivo new. E pode parecer que não há nada para administrar aqui, mas não é assim. Podem surgir dificuldades quando nossa aplicação possui uma determinada classe que possui muitos descendentes, sendo necessário criar uma instância de uma determinada classe dependendo de algumas condições. Factory é um padrão de design que ajuda a resolver o problema de criação de objetos diferentes dependendo de algumas condições. Abstrato, não é? Mais especificidade e clareza aparecerão quando observarmos o exemplo abaixo.

Criamos diferentes tipos de café

Digamos que queremos automatizar uma cafeteria. Precisamos aprender a preparar diferentes tipos de café. Para isso, em nosso aplicativo criaremos uma classe de café e seus derivados: Americano, cappuccino, espresso, latte - esses tipos de café que iremos preparar. Vamos começar com a aula geral de café:
public class Coffee {
    public void grindCoffee(){
        // перемалываем кофе
    }
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
A seguir, vamos criar seus herdeiros:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Nossos clientes irão pedir algum tipo de café, e essa informação precisa ser repassada ao programa. Isso pode ser feito de diferentes maneiras, por exemplo, usando String. Mas é mais adequado para esses fins enum. Vamos criar enume definir nele os tipos de café para os quais aceitamos pedidos:
public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
Ótimo, agora vamos escrever o código da nossa cafeteria:
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("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}
O método orderCoffeepode ser dividido em dois componentes:
  1. Criando uma instância específica de café em um bloco switch-case. É aqui que o que a Fábrica faz é a criação de um tipo específico dependendo das condições.
  2. A preparação em si é moer, cozinhar e despejar em uma xícara.
O que é importante saber se você precisar fazer alterações no método no futuro:
  1. O próprio algoritmo de preparação (moer, cozinhar e despejar em uma xícara) permanecerá inalterado (pelo menos assim esperamos).
  2. Mas a gama de café pode mudar. Talvez comecemos a fazer mocha.. Mocha.. Mokkachi... Deus o abençoe, um novo tipo de café.
Já podemos assumir que no futuro, com um certo grau de probabilidade, teremos que fazer alterações no método, no bloco switch-case. Também é possível que na nossa cafetaria o método orderCoffeenão seja o único local onde criamos diferentes tipos de café. Portanto, alterações terão que ser feitas em diversos locais. Você provavelmente já entendeu o que quero dizer. Precisamos refatorar. Mova o bloco responsável pela criação do café para uma classe separada por dois motivos:
  1. Poderemos reaproveitar a lógica de criação do café em outros lugares.
  2. Se o intervalo mudar, não teremos que editar o código em todos os lugares onde a criação de café será usada. Bastará alterar o código em apenas um local.
Em outras palavras, é hora de desmontar a fábrica.

Estamos serrando nossa primeira fábrica

Para isso, vamos criar uma nova classe que será responsável apenas por criar as instâncias necessárias das classes coffee:
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;
    }
}
Parabéns! Acabamos de implementar o padrão de design Factory em sua forma mais simples. Embora tudo pudesse ser ainda mais simples se o método se tornasse createCoffeeestático. Mas então perderíamos duas possibilidades:
  1. Herdar SimpleCoffeeFactorye substituir o createCoffee.
  2. Implemente a implementação de fábrica necessária em nossas aulas.
Falando em implementação. Precisamos voltar à cafeteria e implementar nossa fábrica de café.

Introdução de uma fábrica em uma cafeteria

Vamos reescrever nossa aula de cafeteria usando uma 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("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}
Ótimo. Agora vamos tentar descrever de forma esquemática e concisa a estrutura do padrão de design Factory.

5 passos para abrir sua própria fábrica

Passo 1. No seu programa você tem uma classe com vários descendentes, como na figura abaixo: Padrão de Design de Fábrica - 2Passo 2. Você cria uma classe enumna qual você define uma variável enum para cada classe descendente:
enum CatType {
    LION,
    TIGER,
    BARSIK
}
Etapa 3. Você constrói sua fábrica. Você chama MyClassFactory, o código está abaixo:
class CatFactory {}
Etapa 4. Você cria um método em sua fábrica createMyClassque usa a variável - enum MyClassType. Código abaixo:
class CatFactory {
    public Cat createCat(CatType type) {

    }
}
Etapa 5. Você escreve um bloco no corpo do método switch-caseno qual itera todos os valores enum e cria uma instância da classe correspondente ao enumvalor:
class CatFactory {
        public Cat createCat(CatType type) {
            Cat cat = null;

            switch (type) {
                case LION:
                    cat =  new Barsik();
                    break;
                case TIGER:
                    cat = new Tiger();
                    break;
                case BARSIK:
                    cat =  new Lion();
                    break;
            }

            return cat;
        }
    }
Que nem um chefe.

Como treinar

Ler é bom, escrever código é ainda melhor. Se o seu nome tiver número par de letras, experimente criar sua própria pizzaria virtual. Se o seu nome tiver um número ímpar de letras, tente criar um sushi bar virtual. Se você é anônimo, você tem sorte. Hoje você pode descansar.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION