| title | Builder | |
|---|---|---|
| categories | Creational | |
| language | pt | |
| tag |
|
Separe a construção de um objeto complexo de sua representação para que a mesma construção do processo possa criar diferentes representações.
Exemplo do Mundo Real
Imagine um gerador de personagens para um jogo de RPG. A opção mais fácil é deixar que o computador crie o personagem para você. Se você quiser selecionar manualmente os detalhes do personagem como profissão, gênero, cor de cabelo, etc. a geração do personagem se torna um processo passo a passo que termina quando todas as seleções estiverem prontas.
Em outras palavras
Permite criar diferentes formas de um objeto, evitando a poluição do construtor. Útil quando pode haver várias formas de um objeto. Ou quando há muitos passos envolvidos na criação de um objeto.
De acordo com a Wikipédia
o Builder constrói objetos complexos passo a passo e procura evitar ser um anti-padrão.
Dito isso, deixe-me acrescentar um pouco sobre o que é o antipadrão do construtor. Em um ponto ou o outro, todos nós vimos um construtor como abaixo:
public Hero(Profession profession, String name, HairType hairType, HairColor hairColor, Armor armor, Weapon weapon) {
}Como você pode ver, o número de parâmetros do construtor pode ficar rapidamente fora de controle e pode se tornar difícil entender a disposição dos parâmetros. Além disso, esta lista de parâmetros pode continuar crescendo se você quiser adicionar mais opções no futuro. Isso é chamado de construtor telescópico anti-padrão.
Exemplo Programático
A alternativa sensata é usar o padrão Builder. Em primeiro lugar, temos o nosso herói que queremos criar:
public final class Hero {
private final Profession profession;
private final String name;
private final HairType hairType;
private final HairColor hairColor;
private final Armor armor;
private final Weapon weapon;
private Hero(Builder builder) {
this.profession = builder.profession;
this.name = builder.name;
this.hairColor = builder.hairColor;
this.hairType = builder.hairType;
this.weapon = builder.weapon;
this.armor = builder.armor;
}
}Então temos o builder:
public static class Builder {
private final Profession profession;
private final String name;
private HairType hairType;
private HairColor hairColor;
private Armor armor;
private Weapon weapon;
public Builder(Profession profession, String name) {
if (profession == null || name == null) {
throw new IllegalArgumentException("profession and name can not be null");
}
this.profession = profession;
this.name = name;
}
public Builder withHairType(HairType hairType) {
this.hairType = hairType;
return this;
}
public Builder withHairColor(HairColor hairColor) {
this.hairColor = hairColor;
return this;
}
public Builder withArmor(Armor armor) {
this.armor = armor;
return this;
}
public Builder withWeapon(Weapon weapon) {
this.weapon = weapon;
return this;
}
public Hero build() {
return new Hero(this);
}
}Então pode ser usado como:
var mage = new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK).withWeapon(Weapon.DAGGER).build();Use o padrão Builder quando
- O algoritmo para criar um objeto complexo deve ser independente das partes que compõem o objeto e de como elas são montadas
- O processo de construção deve permitir diferentes representações para o objeto construído
- java.lang.StringBuilder
- java.nio.ByteBuffer bem como buffers semelhantes, como FloatBuffer, IntBuffer e assim por diante.
- java.lang.StringBuffer
- Todas as implementações de java.lang.Appendable
- Apache Camel builders
- Apache Commons Option.Builder
