1
resposta

Código alternativo do padrão State

Já estudei o padrão State em algum outro momento e achei estranho utilizar o modificador protected nos atributos da classe. Talvez essa abordagem tenha sido utilizada nos exemplos da aula para facilitar o entendimento, mas não seria mais interessante encapsular esses atributos em métodos?

Seguem os códigos alternativos que desenvolvi. Percebam que nas classes ContaPositiva e ContaNegativa optei por apenas calcular o valor de desconto e deixei a classe ContaBancaria continuar calculando o saldo. Essa abordagem é mais coesa na opinião de vocês?

public interface ContaState {
    void positivar(ContaBancaria conta);
    void negativar(ContaBancaria conta);
    double depositar(double valor);
    double sacar(double valor);
}
/**
 * Uma conta que está com saldo positivo, aceita saques
 * e o banco deposita 98% do valor do depósito.
 */
public class ContaPositiva implements ContaState {

    @Override
    public void positivar(ContaBancaria conta) {
        throw new RuntimeException("Conta já está positiva!");
    }

    @Override
    public void negativar(ContaBancaria conta) {
        conta.alterarEstado(new ContaNegativa());
    }

    @Override
    public double depositar(double valor) {
       return valor * 0.98;
    }

    @Override
    public double sacar(double valor) {
        return valor;
    }
}
/**
 * Uma conta que está negativo, por exemplo, não aceita saques e
 * depositam apenas 95% do valor total de um depósito efetuado.
 */
public class ContaNegativa implements ContaState {

    @Override
    public void positivar(ContaBancaria conta) {
        conta.alterarEstado(new ContaPositiva());
    }

    @Override
    public void negativar(ContaBancaria conta) {
        throw new RuntimeException("Conta já está negativa!");
    }

    @Override
    public double depositar(double valor) {
        return valor * 0.95;
    }

    @Override
    public double sacar(double valor) {
        throw new RuntimeException("Não é possível sacar quando saldo está negativo. Por favor, efetue um depósito!");
    }
}
public class ContaBancaria {

    private ContaState estado;
    private double saldo;

    public ContaBancaria() {
        saldo = 0.0;
        estado = new ContaPositiva();
    }

    public double getSaldo() {
        return saldo;
    }

    public void depositar(double valor) {
        double valorDeposito = estado.depositar(valor);
        saldo += valorDeposito;
        if (estado instanceof ContaNegativa && saldo > 0) {
            estado.positivar(this);
        }
    }

    public double sacar(double valor) {
        double valorSacado = estado.sacar(valor);
        saldo -= valorSacado;

        if (estado instanceof ContaPositiva && saldo < 0) {
            estado.negativar(this);
        }

        return this.getSaldo();
    }

    void alterarEstado(ContaState estado) {
        this.estado = estado;
    }
}
1 resposta

ContaPositiva.sacar() retorna o valor diretamente?

Acredito que ficou mais coeso da forma que você fez ;)