Padrão Builder
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 67 de 87.
O Builder Pattern é um padrão de projeto criacional que resolve um problema comum: construir objetos complexos com muitos parâmetros opcionais. Em vez de criar vários construtores ou passar null para parâmetros não utilizados, o Builder permite construir objetos passo a passo.
Considere criar um objeto User com campos obrigatórios (nome, e-mail) e opcionais (idade, telefone, endereço). Sem um Builder, você precisaria de construtores telescópicos ou de um construtor confuso com muitos parâmetros. O padrão Builder oferece uma abordagem mais organizada:
public class User {
private final String name; // obrigatório
private final String email; // obrigatório
private final int age; // opcional
private final String phone; // opcional
private User(UserBuilder builder) {
this.name = builder.name;
this.email = builder.email;
this.age = builder.age;
this.phone = builder.phone;
}
public static class UserBuilder {
private final String name;
private final String email;
private int age;
private String phone;
public UserBuilder(String name, String email) {
this.name = name;
this.email = email;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public User build() {
return new User(this);
}
}
}Os métodos do Builder retornam this, permitindo o : uma maneira fluente e legível de construir objetos:
User user = new User.UserBuilder("Alice", "alice@email.com")
.age(25)
.phone("555-1234")
.build();Observe como o construtor de User é privado: os objetos só podem ser criados por meio do Builder. Esse padrão se destaca quando os objetos têm muitos campos opcionais, tornando seu código mais legível e menos sujeito a erros do que listas longas de parâmetros.
Desafio
FácilVamos criar um sistema de pedidos de pizza usando o Padrão Builder! Em vez de lidar com um construtor que recebe dezenas de parâmetros para todas as possíveis coberturas e opções, você criará um builder fluente que torna a personalização da pizza simples e legível.
Você organizará seu código em dois arquivos:
Pizza.java: Crie uma classePizzaque use o Padrão Builder para a construção. Sua pizza deve ter os seguintes campos:size(String) - obrigatório, representa o tamanho da pizzacheese(boolean) - opcional, o padrão é falsepepperoni(boolean) - opcional, o padrão é falsemushrooms(boolean) - opcional, o padrão é falseO construtor de
Pizzadeve ser privado e aceitar apenas umPizzaBuildercomo parâmetro, copiando todos os valores do builder para os campos da pizza.Inclua um método
getDescription()que retorne uma string neste formato:[size] Pizza with: [toppings], em que toppings é uma lista separada por vírgulas das coberturas que são true (Cheese, Pepperoni, Mushrooms). Se nenhuma cobertura for selecionada, a parte de toppings deve simplesmente dizerno toppings.Crie uma classe interna estática
PizzaBuildercom:- Um construtor que receba o parâmetro obrigatório
size - Métodos
cheese(),pepperoni()emushrooms()que definam cada booleano correspondente como true e retornemthispara encadeamento - Um método
build()que retorne uma novaPizza
- Um construtor que receba o parâmetro obrigatório
Main.java: Demonstre seu builder de pizza em ação! Você receberá quatro entradas: o tamanho da pizza (String) e três valores sim/não (Strings) indicando se deve adicionar queijo, pepperoni e cogumelos, respectivamente.Crie um
PizzaBuildercom o tamanho fornecido. Em seguida, com base em cada entrada sim/não, encadeie os métodos de cobertura apropriados. Se a entrada for"yes", chame o método da cobertura correspondente; se for"no", ignore-o. Por fim, chamebuild()para criar sua pizza.Imprima o resultado da chamada de
getDescription()na pizza concluída.
Você receberá quatro entradas na seguinte ordem: tamanho (String), adicionar queijo (String: "yes" ou "no"), adicionar pepperoni (String: "yes" ou "no"), adicionar cogumelos (String: "yes" ou "no").
Por exemplo, com as entradas Large, yes, no, yes, sua saída seria: Large Pizza with: Cheese, Mushrooms
Observe como o Padrão Builder permite construir pizzas com qualquer combinação de coberturas sem precisar de construtores separados para cada possibilidade!
Experimente você mesmo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Ler entradas
String size = scanner.nextLine();
String addCheese = scanner.nextLine();
String addPepperoni = scanner.nextLine();
String addMushrooms = scanner.nextLine();
// TODO: Crie um PizzaBuilder com o tamanho fornecido
// TODO: Encadeie os métodos de cobertura com base nas entradas sim/não
// TODO: Construa a pizza e imprima sua descrição
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão IteratorPratique por conta própria: Compilador de Java online