3
respostas

É má prática chamar métodos sets dentro dos construtores?

public class Conta {
    private int numero;

    public Conta(numero) {
        this.setNumero(numero);
    }

    public void setNumero(int numero) {
        if(numero <= 0) {
            System.out.println("O número não pode ser <= 0");
            return;
        }
        this.numero = numero;
    }

}

Nesse cenário eu sou obrigado a passar um número válido para conta na construção do objeto e posso futuramente alterar seu valor usando o método set. Minha dúvida é: É melhor eu repetir a validação no construtor ou é melhor chamar o set que já faz a validação dentro do construtor? Pergunto isso pois li algumas discussões no stackoverflow sobre problemas que isso pode acarretar, principalmente se os métodos não forem finais.

3 respostas

Olá, Luan.

O seu questionamento é excelente!

A convenção no Java é usar this.atributo = valor; mesmo. E a maioria dos desenvolvedores nem vai questionar isso. Tradição, costume, sabe? hehe

Seria um argumento a favor de repetir.

Outro argumento seria esse que você falou: você não deveria chamar um método público e não final no construtor pois eles podem ser sobrescritos e não dá pra saber o comportamento.

Um meio-termo seria criar um método private que faz a validação. Métodos privados não podem ser sobrescritos!

Olá, Alexandre.

Quando você diz que é convenção do Java usar this.atributo = valor para mim que estou iniciando em Java não entra na minha cabeça pois estariamos aceitando um valor que potenciamente pode estar inválido como por exemplo um CPF que um usário pode digitar.

Então só pra confirmar, imagine o seguinte cenário: existem dois formulários com os campos nome e CPF, um formulário para cadastro e outro para edição. Os dois campos são obrigatórios na instanciação do objeto, então um esboço da minha classe seria:

public class Pessoa {
    private String nome;
    private String cpf;

    public Pessoa(String nome, String cpf) {
        // Se eu fizesse this.cpf = cpf; algum valor inválido seria atribuido, por isso não entendi a convenção :/
        validaNome(nome);
        validaCPF(cpf);
    }

    public void setNome(String nome) {
        validaNome(nome);
    }

    public void setCPF(String cpf) {
        validaCPF(cpf);
    }

    private final void validaNome(String nome) {
        if(nome.length < 5) {
            throw new IllegalArgumentException("O campo nome deve ter no minímo 5 caracteres");
        }
        this.nome = nome;
    }

    private final void validaCPF(String cpf) {

        if(cpf nao é valido) {
            throw new IllegalArgumentException("O CPF informado não é válido");
        }
        this.cpf = cpf;
    }



}

Talvez eu esteja apressando muito as coisas mas no momento que estou aprendendo é isso que tendo a fazer em todas as minhas classes, inicialmente eu faria as validações nos métodos sets e lançaria exceções nos casos onde as validações não passassem e daí utilizaria esses métodos sets no construtor mas como vi que isso não é boa prática agora tendo a criar esses métodos private final que eu posso utilizar tanto nos sets quanto nos construtores evitando assim repetição de código. É esse o caminho ou estou inventando muita coisa?

Olá, Luan!

É bem por aí mesmo. Exceções ainda não foram abordadas no curso, né?

Mas parabéns pelas reflexões! É assim que a gente aprende e conecta as ideias!