Oi amigo! Hoje vamos continuar a estudar padrões de projeto. Nesta lição, vamos falar sobre fábricas. Discutiremos o problema que esse padrão resolve e veremos um exemplo de como uma fábrica pode ajudá-lo a abrir uma cafeteria. Além disso, darei a você 5 etapas simples para criar uma fábrica.
Para ter certeza de que estamos todos no mesmo comprimento de onda e que você entenderá rapidamente esse conceito, você deve estar familiarizado com os seguintes tópicos:
Passo 2. Você cria um

- Herança em Java
- Limitação e ampliação de tipos de referência em Java
- Interação entre diferentes classes e objetos.
O que é uma fábrica?
O padrão de design de fábrica permite controlar a criação de objetos. O processo de criação de um novo objeto não é super simples, mas também não é excessivamente complicado. Todos nós sabemos que precisamos donew
operador para criar um novo objeto. Talvez pareça que não há nada para controlar aqui, mas isso não é verdade. Suponha que nosso aplicativo tenha uma determinada classe com muitos descendentes. Dificuldades podem surgir quando é necessário criar uma instância de uma classe específica dependendo de certas condições. Uma fábrica é um padrão de projeto que ajuda a resolver o problema de criar vários objetos dependendo de certas condições. Como é isso para um conceito abstrato? Isso ficará mais claro e específico quando olharmos para o exemplo abaixo.
Vamos preparar vários tipos de café
Suponha que queremos automatizar uma cafeteria. Precisamos ensinar nosso programa a fazer diferentes tipos de café. Para isso, criaremos uma classe de café e algumas classes derivadas para representar os tipos de café que iremos preparar: Americano, cappuccino, espresso e latte. Vamos começar com uma aula geral de café:
public class Coffee {
public void grindCoffee(){
// Grind the coffee
}
public void makeCoffee(){
// Brew the coffee
}
public void pourIntoCup(){
// Pour into a cup
}
}
Em seguida, criaremos suas classes filhas:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Nossos clientes podem pedir qualquer tipo de café. Seus pedidos precisam ser passados para o programa. Isso pode ser feito de várias maneiras, por exemplo, usando String
. Mas um enum
é melhor para isso. Vamos criar enum
e definir campos enum que correspondem aos tipos de café que podem ser pedidos:
public enum CoffeeType {
ESPRESSO,
AMERICANO,
CAFFE_LATTE,
CAPPUCCINO
}
Ótimo. Agora vamos escrever o código para 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("Here's your coffee! Thanks! Come again!");
return coffee;
}
}
O orderCoffee
método pode ser dividido em duas partes:
- Criação de uma instância específica de café em uma
switch
instrução. É aqui que uma fábrica faz o que faz - cria um tipo específico dependendo das condições. - Preparação - esta é a moagem, fermentação e derramamento em um copo.
- As etapas envolvidas na preparação em si (moer, preparar e despejar em um copo) permanecerão inalteradas (pelo menos estamos contando com isso).
- Mas a variedade de cafés pode mudar. Talvez comecemos a fazer mocha... Frappu... Mochacci... Tanto faz, um novo tipo de café.
switch
instrução do método. Também é possível que em nossa cafeteria o orderCoffee
método não seja o único lugar onde criaremos diferentes tipos de café. Como resultado, mudanças terão que ser feitas em vários lugares. Você provavelmente já entendeu onde quero chegar. Precisamos refatorar. Mova o bloco responsável pela criação do café para uma classe separada por dois motivos:
- Podemos reutilizar a lógica de fazer café em outros lugares.
- Se o sortimento mudar, não teremos que editar o código em todos os lugares onde o café é criado. Será o suficiente para alterar nosso código em apenas um lugar.
Montando nossa primeira fábrica
Para isso, criaremos uma nova classe que será responsável apenas por criar as instâncias necessárias das classes 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;
}
}
Parabéns! Acabamos de implementar o padrão de projeto de fábrica em sua forma mais simples (quase). Poderia ter sido ainda mais simples se fizéssemos o createCoffee
método estático. Mas então perderíamos duas capacidades:
- A capacidade de herdar
SimpleCoffeeFactory
e substituir ocreateCoffee
método. - A capacidade de adicionar a implementação de fábrica necessária às nossas aulas.
Adicionando uma fábrica à cafeteria
Vamos reescrever a classe coffee shop 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("Here's your coffee! Thanks! Come again!");
return coffee;
}
}
Excelente. Agora forneceremos uma descrição concisa da estrutura geral do padrão de projeto de fábrica.
5 passos para abrir sua própria fábrica
Passo 1. Seu programa possui uma classe com vários descendentes, conforme o diagrama abaixo:
enum
an com um campo para cada classe filha:
enum CatType {
LION,
TIGER,
FLUFFY
}
Passo 3. Construa sua fábrica. Chame-o CatFactory
. Aqui está o código:
class CatFactory {}
Etapa 4. Em sua fábrica, crie um createCat
método que receba um CatType
argumento. Aqui está o código:
class CatFactory {
public Cat createCat(CatType type) {
}
}
Etapa 5. No corpo do método, escreva uma switch
instrução que enumera os campos enum e crie uma instância da classe que corresponde ao enum
valor passado:
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;
}
}
Agora você pode administrar uma fábrica como um chefe. :)
GO TO FULL VERSION