25
loading...
This website collects cookies to deliver better user experience
public class Lanche {
private final Tamanho tamanho;
private final Pao pao;
private final Recheio recheio;
private final Queijo queijo;
private final List<Vegetais> vegetais;
private final Molho molho;
public Lanche(Tamanho tamanho, Pao pao, Recheio recheio,
Queijo queijo, List<Vegetais> vegetais,
Molho molho) {
this.tamanho = tamanho;
this.pao = pao;
this.recheio = recheio;
this.queijo = queijo;
this.vegetais = vegetais;
this.molho = molho;
}
}
new Lanche(Tamanho.GRANDE,Pao.PARMESAO_OREGANO,Recheio.CHURRASCO,
Queijo.PRATO, List.of(Vegetal.ALFACE, Vegetal.CEBOLA),
Molho.CHIPOTLE);
A quantidade ideal de parâmetros para uma função é zero (nulo).
Depois vem um (mônade), seguido de dois (díade).
Sempre que possivel, devem-se evitar três parâmetros (tríade).
Para mais de três, deve-se ter um motivo muito especial (políade) - mesmo assim não devem ser utilizados.
public class Lanche {
private final Tamanho tamanho;
private final Pao pao;
private final Recheio recheio;
private final Queijo queijo;
private final List<Vegetal> vegetais;
private final Molho molho;
private Lanche(LancheBuilder lancheBuilder) {
this.tamanho = lancheBuilder.tamanho;
this.pao = lancheBuilder.pao;
this.recheio = lancheBuilder.recheio;
this.queijo = lancheBuilder.queijo;
this.vegetais = lancheBuilder.vegetais;
this.molho = lancheBuilder.molho;
}
public static LancheBuilder umLanche() {
return new LancheBuilder();
}
public static class LancheBuilder {
private Tamanho tamanho;
private Pao pao;
private Recheio recheio;
private Queijo queijo;
private List<Vegetal> vegetais;
private Molho molho;
//Nao deixando chamar o construtor de fora desta classe
private LancheBuilder() {
}
public LancheBuilder grande() {
this.tamanho = Tamanho.GRANDE;
return this;
}
public LancheBuilder normal() {
this.tamanho = Tamanho.NORMAL;
return this;
}
public LancheBuilder comPao(Pao pao) {
this.pao = pao;
return this;
}
public LancheBuilder comRecheio(Recheio recheio) {
this.recheio = recheio;
return this;
}
public LancheBuilder comQueijo(Queijo queijo) {
this.queijo = queijo;
return this;
}
public LancheBuilder comVegetais(Vegetal... vegetais) {
this.vegetais = List.of(vegetais);
return this;
}
public LancheBuilder comMolho(Molho molho) {
this.molho = molho;
return this;
}
public Lanche constroi() {
return new Lanche(this);
}
}
}
Lanche.umLanche().grande()
.comPao(PARMESAO_OREGANO)
.comMolho(CHIPOTLE)
.comQueijo(PRATO)
.comRecheio(CHURRASCO)
.comVegetais(ALFACE, CEBOLA)
.constroi();
Lanche
como privado e disponibilizei o método umLanche
, que devolve um Builder. Isso está descrito no livro Java Efetivo (Effective Java de Joshua Bloch) e é chamado de static factory. Diferente dos construtores conseguimos nomeá-los, fazendo com que fiquem mais descritivos. Além disso, podemos retornar um objeto que a princípio não é o mesmo de nossa classe.Lanche
só temos um parâmetro no construtor: o LancheBuilder
.Lanche.umLanche().constroi();
public class Lanche {
private final Tamanho tamanho;
private final Pao pao;
private final Recheio recheio;
private final Queijo queijo;
private final List<Vegetal> vegetais;
private final Molho molho;
private Lanche(LanchePassoFinalBuilder lanchePassoFinalBuilder) {
this.tamanho = lanchePassoFinalBuilder.tamanho;
this.pao = lanchePassoFinalBuilder.pao;
this.recheio = lanchePassoFinalBuilder.recheio;
this.queijo = lanchePassoFinalBuilder.queijo;
this.vegetais = lanchePassoFinalBuilder.vegetais;
this.molho = lanchePassoFinalBuilder.molho;
}
public static LancheBuilder umLanche(Recheio recheio, Pao pao) {
return new LancheBuilder(recheio, pao);
}
static class LancheBuilder {
private final Recheio recheio;
private final Pao pao;
private LancheBuilder(Recheio recheio, Pao pao) {
this.recheio = recheio;
this.pao = pao;
}
public LancheTerceiroPassoBuilder grande() {
return new LancheTerceiroPassoBuilder(recheio, pao,
Tamanho.GRANDE);
}
public LancheTerceiroPassoBuilder normal() {
return new LancheTerceiroPassoBuilder(recheio, pao,
Tamanho.NORMAL);
}
}
static class LancheTerceiroPassoBuilder {
private final Recheio recheio;
private final Pao pao;
private final Tamanho tamanho;
public LancheTerceiroPassoBuilder(Recheio recheio,
Pao pao,
Tamanho tamanho) {
this.recheio = recheio;
this.pao = pao;
this.tamanho = tamanho;
}
public LancheQuartoPassoBuilder comQueijo(Queijo queijo) {
return new LancheQuartoPassoBuilder(recheio,
pao, tamanho, queijo);
}
}
static class LancheQuartoPassoBuilder {
private final Recheio recheio;
private final Pao pao;
private final Tamanho tamanho;
private final Queijo queijo;
public LancheQuartoPassoBuilder(Recheio recheio,
Pao pao, Tamanho tamanho,
Queijo queijo) {
this.recheio = recheio;
this.pao = pao;
this.tamanho = tamanho;
this.queijo = queijo;
}
public LanchePassoFinalBuilder comVegetais(Vegetal... vegetais) {
return new LanchePassoFinalBuilder(tamanho,
recheio, pao,
queijo, List.of(vegetais));
}
}
static class LanchePassoFinalBuilder {
private final Tamanho tamanho;
private final Recheio recheio;
private final Pao pao;
private final Queijo queijo;
private final List<Vegetal> vegetais;
private Molho molho;
public LanchePassoFinalBuilder(Tamanho tamanho,
Recheio recheio, Pao pao,
Queijo queijo,
List<Vegetal> vegetais) {
this.tamanho = tamanho;
this.recheio = recheio;
this.pao = pao;
this.queijo = queijo;
this.vegetais = vegetais;
}
public LanchePassoFinalBuilder comMolho(Molho molho) {
this.molho = molho;
return this;
}
public Lanche build() {
return new Lanche(this);
}
}
}
Lanche.umLanche(CHURRASCO, TRES_QUEIJOS)
.grande()
.comQueijo(PRATO)
.comVegetais(CEBOLA, TOMATE, ALFACE)
.comMolho(CHIPOTLE)
.build();
Lanche
.public interface CriacaoLanchePassos {
interface LancheBuilder {
LancheTerceiroPasso grande();
LancheTerceiroPasso normal();
}
interface LancheTerceiroPasso {
LancheQuartoPasso comQueijo(Queijo queijo);
}
interface LancheQuartoPasso {
LanchePassoFinal comVegetais(Vegetal... vegetais);
}
interface LanchePassoFinal {
LanchePassoFinal comMolho(Molho molho);
Lanche build();
}
}
public class Lanche {
private final Tamanho tamanho;
private final Pao pao;
private final Recheio recheio;
private final Queijo queijo;
private final List<Vegetal> vegetais;
private final Molho molho;
private Lanche(LanchePassoFinalBuilder lanchePassoFinalBuilder) {
this.tamanho = lanchePassoFinalBuilder.tamanho;
this.pao = lanchePassoFinalBuilder.pao;
this.recheio = lanchePassoFinalBuilder.recheio;
this.queijo = lanchePassoFinalBuilder.queijo;
this.vegetais = lanchePassoFinalBuilder.vegetais;
this.molho = lanchePassoFinalBuilder.molho;
}
public static CriacaoLanchePassos.LancheBuilder umLanche(Recheio recheio, Pao pao) {
return new LancheBuilder(recheio, pao);
}
private static class LancheBuilder implements CriacaoLanchePassos.LancheBuilder {
private final Recheio recheio;
private final Pao pao;
public LancheBuilder(Recheio recheio, Pao pao) {
this.recheio = recheio;
this.pao = pao;
}
public CriacaoLanchePassos.LancheTerceiroPasso grande() {
return new LancheTerceiroPassoBuilder(recheio, pao,
Tamanho.GRANDE);
}
public CriacaoLanchePassos.LancheTerceiroPasso normal() {
return new LancheTerceiroPassoBuilder(recheio, pao,
Tamanho.NORMAL);
}
}
private static class LancheTerceiroPassoBuilder implements CriacaoLanchePassos.LancheTerceiroPasso {
private final Recheio recheio;
private final Pao pao;
private final Tamanho tamanho;
private LancheTerceiroPassoBuilder(Recheio recheio,
Pao pao,
Tamanho tamanho) {
this.recheio = recheio;
this.pao = pao;
this.tamanho = tamanho;
}
public CriacaoLanchePassos.LancheQuartoPasso comQueijo(Queijo queijo) {
return new LancheQuartoPassoBuilder(recheio,
pao, tamanho, queijo);
}
}
private static class LancheQuartoPassoBuilder implements CriacaoLanchePassos.LancheQuartoPasso {
private final Recheio recheio;
private final Pao pao;
private final Tamanho tamanho;
private final Queijo queijo;
private LancheQuartoPassoBuilder(Recheio recheio,
Pao pao, Tamanho tamanho,
Queijo queijo) {
this.recheio = recheio;
this.pao = pao;
this.tamanho = tamanho;
this.queijo = queijo;
}
public CriacaoLanchePassos.LanchePassoFinal comVegetais(Vegetal... vegetais) {
return new LanchePassoFinalBuilder(tamanho,
recheio, pao,
queijo, List.of(vegetais));
}
}
private static class LanchePassoFinalBuilder implements CriacaoLanchePassos.LanchePassoFinal {
private final Tamanho tamanho;
private final Recheio recheio;
private final Pao pao;
private final Queijo queijo;
private final List<Vegetal> vegetais;
private Molho molho;
private LanchePassoFinalBuilder(Tamanho tamanho,
Recheio recheio, Pao pao,
Queijo queijo,
List<Vegetal> vegetais) {
this.tamanho = tamanho;
this.recheio = recheio;
this.pao = pao;
this.queijo = queijo;
this.vegetais = vegetais;
}
public LanchePassoFinalBuilder comMolho(Molho molho) {
this.molho = molho;
return this;
}
public Lanche build() {
return new Lanche(this);
}
}
}
primeira_refatoracao
, segunda_refatoracao
e terceira_refatoracao
.Código limpo (Clean code de Robert C. Martin) - https://amzn.to/3jzA8vh
Java Efetivo (Effective Java de Joshua Bloch) - https://amzn.to/3yeSd67
Padrões de Projetos: Soluções Reutilizáveis de Software Orientados a Objetos(Design Patterns: Elements of Reusable Object-Oriented Software de GOF) - https://amzn.to/3h99Sq9