Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

README.md

title Builder
categories Creational
language pt
tag
Gang of Four

Propósito

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.

Explicação

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();

Diagrama de classes

alt text

Aplicabilidade

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

Tutoriais

Usos conhecidos

Créditos