O Padrão de Estado é um padrão de design comportamental que permite a um objeto modificar sua ação com base em seu estado interno. Neste artigo, aplicamos esse padrão para simular uma conta bancária com três estados distnitos, determinados pelo saldo da conta. O objetivo é ilustrar como operações como depósito e saque podem desencadear trensições automáticas antre estados, mantendo o código modular e extensível.
Definição dos estados da conta bancária:
- Estado Normal (Verde): Saldo ≥ 0. Permite depósitos e saques.
- Estado Atrasado (Amarelo): Saldo < 0 e ≥ -1000. Permite depósitos e saques.
- Estado Sobregirado (Vermelho): Saldo < -1000. Permite apenas depósitos, bloqueando saques.
Implementação em C++ utilizando o Padrão de Estado:
#include <iostream>
#include <string>
class ContaBancaria;
class EstadoConta {
public:
ContaBancaria* conta;
double saldo;
std::string nomeEstado;
virtual void verificarEstado() = 0;
virtual void depositar(double valor) {
std::cout << conta->getDono() << " realizou depósito de " << valor << std::endl;
saldo += valor;
verificarEstado();
std::cout << "Saldo atual: " << saldo << std::endl;
std::cout << "Estado atual: " << conta->getEstado()->nomeEstado << std::endl;
}
virtual void sacar(double valor) {
std::cout << conta->getDono() << " realizou saque de " << valor << std::endl;
saldo -= valor;
verificarEstado();
std::cout << "Saldo atual: " << saldo << std::endl;
std::cout << "Estado atual: " << conta->getEstado()->nomeEstado << std::endl;
}
};
class ContaBancaria {
private:
EstadoConta* estado;
std::string dono;
public:
ContaBancaria(std::string nome, double saldoInicial);
void setEstado(EstadoConta* novoEstado) {
this->estado = novoEstado;
}
EstadoConta* getEstado() {
return this->estado;
}
std::string getDono() {
return this->dono;
}
void depositar(double valor) {
estado->depositar(valor);
}
void sacar(double valor) {
estado->sacar(valor);
}
};
class EstadoVermelho : public EstadoConta {
public:
EstadoVermelho(EstadoConta* estadoAnterior) {
this->saldo = estadoAnterior->saldo;
this->conta = estadoAnterior->conta;
this->nomeEstado = "Sobregirado";
}
void sacar(double valor) override {
std::cout << "Conta em estado sobregirado: saque não permitido!" << std::endl;
}
void verificarEstado() override;
};
class EstadoAmarelo : public EstadoConta {
public:
EstadoAmarelo(EstadoConta* estadoAnterior) {
this->saldo = estadoAnterior->saldo;
this->conta = estadoAnterior->conta;
this->nomeEstado = "Atrasado";
}
void verificarEstado() override;
};
class EstadoVerde : public EstadoConta {
public:
EstadoVerde(double saldoInicial, ContaBancaria* conta) {
this->saldo = saldoInicial;
this->conta = conta;
this->nomeEstado = "Normal";
}
EstadoVerde(EstadoConta* estadoAnterior) {
this->conta = estadoAnterior->conta;
this->saldo = estadoAnterior->saldo;
this->nomeEstado = "Normal";
}
void verificarEstado() override {
if (saldo >= -1000 && saldo < 0) {
conta->setEstado(new EstadoAmarelo(this));
} else if (saldo < -1000) {
conta->setEstado(new EstadoVermelho(this));
} else {
conta->setEstado(new EstadoVerde(this));
}
}
};
void EstadoVermelho::verificarEstado() {
if (saldo >= -1000 && saldo < 0) {
conta->setEstado(new EstadoAmarelo(this));
} else if (saldo < -1000) {
conta->setEstado(new EstadoVermelho(this));
} else {
conta->setEstado(new EstadoVerde(this));
}
}
void EstadoAmarelo::verificarEstado() {
if (saldo >= -1000 && saldo < 0) {
conta->setEstado(new EstadoAmarelo(this));
} else if (saldo < -1000) {
conta->setEstado(new EstadoVermelho(this));
} else {
conta->setEstado(new EstadoVerde(this));
}
}
ContaBancaria::ContaBancaria(std::string nome, double saldoInicial) {
this->dono = nome;
this->estado = new EstadoVerde(saldoInicial, this);
std::cout << "Conta criada para " << dono << " com saldo inicial: " << saldoInicial << std::endl;
std::cout << "----------------------------------------" << std::endl;
}
int main() {
ContaBancaria* conta = new ContaBancaria("Maria", 1000.0);
conta->depositar(200.0);
conta->sacar(400.0);
conta->sacar(900.0);
conta->sacar(1000.0);
delete conta;
return 0;
}
</string></iostream>
Implementação em Java:
package estado;
// Classe que representa a conta bancária
public class ContaBancaria {
private EstadoConta estado;
private String titular;
public ContaBancaria(String titular, double saldoInicial) {
this.titular = titular;
this.estado = new EstadoVerde(saldoInicial, this);
System.out.println("Saldo inicial: " + saldoInicial);
}
public void setEstado(EstadoConta novoEstado) {
this.estado = novoEstado;
}
public void depositar(double valor) {
estado.depositar(valor);
System.out.println("Saldo: " + this.estado.saldo);
}
public void sacar(double valor) {
estado.sacar(valor);
System.out.println("Saldo: " + this.estado.saldo);
}
}
// Classe abstrata para estados da conta
public abstract class EstadoConta {
protected ContaBancaria conta;
protected double saldo;
public abstract void verificar();
public abstract void depositar(double valor);
public abstract void sacar(double valor);
}
// Estado normal (verde)
public class EstadoVerde extends EstadoConta {
public EstadoVerde(double saldo, ContaBancaria conta) {
this.saldo = saldo;
this.conta = conta;
}
@Override
public void verificar() {
if (saldo > 0) {
System.out.println("Estado: Normal");
conta.setEstado(new EstadoVerde(saldo, conta));
} else if (saldo <= 0 && saldo >= -1000) {
System.out.println("Estado: Atrasado");
conta.setEstado(new EstadoAmarelo(saldo, conta));
} else {
System.out.println("Estado: Sobregirado");
conta.setEstado(new EstadoVermelho(saldo, conta));
}
}
@Override
public void depositar(double valor) {
saldo += valor;
verificar();
}
@Override
public void sacar(double valor) {
saldo -= valor;
verificar();
}
}
// Estado atrasado (amarelo)
public class EstadoAmarelo extends EstadoConta {
public EstadoAmarelo(double saldo, ContaBancaria conta) {
this.saldo = saldo;
this.conta = conta;
}
@Override
public void verificar() {
if (saldo > 0) {
System.out.println("Estado: Normal");
conta.setEstado(new EstadoVerde(saldo, conta));
} else if (saldo <= 0 && saldo >= -1000) {
System.out.println("Estado: Atrasado");
conta.setEstado(new EstadoAmarelo(saldo, conta));
} else {
System.out.println("Estado: Sobregirado");
conta.setEstado(new EstadoVermelho(saldo, conta));
}
}
@Override
public void depositar(double valor) {
saldo += valor;
verificar();
}
@Override
public void sacar(double valor) {
saldo -= valor;
verificar();
}
}
// Estado sobregirado (vermelho)
public class EstadoVermelho extends EstadoConta {
public EstadoVermelho(double saldo, ContaBancaria conta) {
this.saldo = saldo;
this.conta = conta;
}
@Override
public void verificar() {
if (saldo > 0) {
System.out.println("Estado: Normal");
conta.setEstado(new EstadoVerde(saldo, conta));
} else if (saldo <= 0 && saldo >= -1000) {
System.out.println("Estado: Atrasado");
conta.setEstado(new EstadoAmarelo(saldo, conta));
} else {
System.out.println("Estado: Sobregirado");
conta.setEstado(new EstadoVermelho(saldo, conta));
}
}
@Override
public void depositar(double valor) {
saldo += valor;
verificar();
}
@Override
public void sacar(double valor) {
System.out.println("Saque bloqueado: conta em estado sobregirado.");
}
}
// Classe de teste
public class TesteConta {
public static void main(String[] args) {
ContaBancaria conta = new ContaBancaria("João", 500.0);
conta.depositar(100.0);
conta.sacar(700.0);
conta.sacar(300.0);
conta.depositar(500.0);
}
}