Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Como restringir para que um atributo seja preenchido apenas uma vez no Builder?

Tenho uma dúvida sobre a aula 08 - Factories, de como melhorar o código conforme mencionado pelo instrutor nos minutos 08:45 até 09:45

public class FabricaDeAluno {

    private Aluno aluno;

    public FabricaDeAluno comNomeCPFEmail(String nome, String cpf, String email) {
        this.aluno = new Aluno(nome, new CPF(cpf), new Email(email));
        return this;
    }

    public FabricaDeAluno comDDDETelefone(String ddd, String numero) {
        this.aluno.adicionarTelefone(ddd, numero);
        return this;
    }

    public Aluno criar() {
        return this.aluno;
    }

        public static void main(String[] args) {

        // Cenário perfeito
        FabricaDeAluno fabricaDeAluno = new FabricaDeAluno();
        Aluno aluno = fabricaDeAluno.comNomeCPFEmail("", "", "")
                .comDDDETelefone("", "").comDDDETelefone("", "").criar();

        // Dois problemas que podem acontecer 
        // 1º Problema
        FabricaDeAluno fabricaDeAluno = new FabricaDeAluno();
        Aluno aluno = fabricaDeAluno
                .comDDDETelefone("", "") // -> Chamar esse método antes do próximo pode gerar um nullPointer
                .comNomeCPFEmail("", "", "")
                .comDDDETelefone("", "")
                .criar();

        // 2º Problema
        FabricaDeAluno fabricaDeAluno = new FabricaDeAluno();
        Aluno aluno = fabricaDeAluno
                .comNomeCPFEmail("", "", "")
                .comDDDETelefone("", "")
                .comNomeCPFEmail("", "", "") // -> Não faz sentido deixar chamar esse método novamente.
                .criar();

    }

Relacionado a esses dois problemas pontuado, como poderia ser refatorada essa classe para que esses problemas não aconteçam ?

Desde já agradeço!

3 respostas

Hemerson, de boa ?

Cara os builders geralmente são assim, fica mais das pessoas que estão utilizando não chamar algo 2 vezes.

Uma forma de restringir isso é a criação de classes internas, dessa maneira você consegue garantir a ordem que seu builder deve chamar cada método e qual é o momento certo criar o objeto concreto.

Basicamente na classe FabricaDeAluno você não devolveria essa instância em cada método, teria algo como FabricaDeAlunoComNomeCPFEmail que só teria o método de colocar telefone e ddd e essa método devolveria FabricaDeAlunoCompleto que você teria o método criar. É bem mais complexo e exige que a pessoa siga cada passo.

Fala Matheus, tudo bem ?

Entendi, se conseguiria me dar um exemplo disso que você comentou no código acima postado ?

Desde já gradeço.

solução!
public class FabricaDeAluno {

    private Aluno aluno;

    public FabricaDeAluno comNomeCPFEmail(String nome, String cpf, String email) {
        this.aluno = new Aluno(nome, new CPF(cpf), new Email(email));
        return this;
    }

    public FabricaDeAlunoComDDDETelefone comDDDETelefone(String ddd, String numero) {
        this.aluno.adicionarTelefone(ddd, numero);
        return FabricaDeAlunoComDDDETelefone(aluno);
    }
}
public class FabricaDeAlunoComDDDETelefone {

        private Aluno aluno;
        //construtor

        public Aluno criar() {
            return aluno;
        }
}