Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Regra de negócio dentro do construtor

Olá a todos. Nas últimas aulas, o professor tinha falado um pouco sobre regra de negócio e numa situação hipotética em que o número das agências não poderiam ser negativas, foi proposto como solução uma condição no método setter setAgencia mais ou menos assim:

public void setAgencia(int agencia) {
        if(numero <= 0) {
            System.out.println("Não pode valor negativo");
            return;
        }
        this.agencia = agencia;
    }

Mas já nos construtores, aparentemente o padrão é simplesmente atribuir diretamente os valores como abaixo:

public Conta(int agencia, int numero) {
        Conta.total++;
        this.agencia = agencia;
        this.numero = numero;    
    }

Mas isso permitiria uma atribuição negativa de número de agência. Uma solução seria escrever condições no construtor mas aí estariamos criando redundância de código (pois já existe um setter que escreve essa lógica). Aí eu pensei em chamar os métodos setters no construtor para essa inicialização mas pesquisando um pouco sobre o assunto, vi que a convenção não é essa, e que essa prática seria, na verdade, ser descorajada pois esses métodos poderiam ser sobreescritos antes da inicialização do construtor. Aí fica a dúvida sobre a melhor maneira de aplicar regras de negócio no construtor.

Espero ter conseguido explicar minha dúvida e agradeço a quem comentar!

3 respostas

Boa noite, Douglas! Como vai?

Nesse caso específico, acho que não faz sentido existir o setAgencia(), afinal de contas, uma vez que o cliente tenha criado uma conta a agência e o número não mudam! Portanto, o melhor nesse caso seria remover o setAgencia() e o setNumero() e deixando no construtor a validação dos valores informados quando da criação do objeto!

Agora, em situações onde tanto o setter quanto o construtor precisam existir, eu centralizaria a lógica no getter como vc sugeriu e, além disso, o modificaria com o final de modo que ele não pudesse ser sobrescrito.

public class MyClass {

    public static void main(String args[]) {
        Child child = new Child();

        System.out.println(child.getName());
    }
}

class Person {

    public final String getName() {
        return "Person";
    }
}

class Child extends Person {

    @Override
    public String getName() {
        return "Child";
    }
}

Esse código irá gerar um erro avisando que getName() não pode ser sobrescrito por ser final!

Pegou a ideia? Qualquer coisa é só falar!

Grande abraço e bons estudos, meu aluno!

Compreendi um pouco mais! Num contexto em que eu só poderia receber números positivos tanto no construtor quanto no setter, poderia ser uma solução eu pegar seu valor absoluto (simplesmente retirar o sinal do número) com um getter que não pode ser sobrescrito?

EX: construtor

public Turma(int sala) {
        this.sala= this.getNumeroAbsoluto(sala);    
    }

EX: setter

public void setSala(int sala) {
        this.sala= this.getNumeroAbsoluto(sala);
    }

EX: getter

public final int getNumeroAbsoluto(int numero) {
    return Math.abs(numero);
}

E também, há alguma contra indicação para o uso do final? Por exemplo, se alguém criar todos os métodos como final, não teria como ninguém alterar um pouco a lógica para os que estendesse tal classe.

Valeu pelas respostas!

Opa, Douglas!

Num contexto em que eu só poderia receber números positivos tanto no construtor quanto no setter, poderia ser uma solução eu pegar seu valor absoluto (simplesmente retirar o sinal do número) com um getter que não pode ser sobrescrito?

Nesse contexto, o correto seria lançar uma exceção caso o número recebido fosse negativo. Poderia ser feito assim:

public Pessoa(int idade) {
     this.idade = setIdade(idade);
}

public final void setIdade(int idade) {
     if (idade < 0) throw new IllegalArgumentException("A idade não pode ser negativa!");

     this.idade = idade;
}

E também, há alguma contra indicação para o uso do final? Por exemplo, se alguém criar todos os métodos como final, não teria como ninguém alterar um pouco a lógica para os que estendesse tal classe.

O que vc precisa ficar atento é que ao colocar o final num método vc não irá conseguir sobrescrevê-lo!

Pegou a ideia? Qualquer coisa é só falar!

Grande abraço e bons estudos, meu aluno!