public class Contrato {
private LocalDate data;
private String cliente;
private EstadoContrato estadoAtual;
public Contrato(LocalDate date, String cliente) {
this.data = date;
this.cliente = cliente;
this.estadoAtual = new Novo(this);
}
public void avanca() {
estadoAtual = estadoAtual.avanca();
}
public void recuperar() {
data = estadoAtual.getContrato().getData();
cliente = estadoAtual.getContrato().getCliente();
}
public LocalDate getData() {
return data;
}
public void setData(LocalDate data) {
this.data = data;
}
public String getCliente() {
return cliente;
}
public EstadoContrato salvaEstado() {
// no momento de salvar o estado
// implementei de uma forma onde o Contrato cria o Estado sozinho
// e o Estado recebe uma instância de contrato
// para chegar no resultado acabei criando um metodo privado para setar o Estado
return new Contrato(data, cliente).setNovoEstado(estadoAtual);
}
private EstadoContrato setNovoEstado(EstadoContrato estadoContrato) {
try {
// verifico qual a classe que representa o estado naquele momento
// e crio uma nova instância.
this.estadoAtual = estadoContrato.getClass().getConstructor(Contrato.class).newInstance(this);
return this.estadoAtual;
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
e.printStackTrace();
throw new RuntimeException("Classe de estado não criada");
}
}
public String getEstadoAtual() {
return estadoAtual.toString();
}
@Override
public String toString() {
return "Cliente: " + cliente + " //Data: " + data + " //" + estadoAtual;
}
}
public abstract class EstadoContrato {
protected Contrato contrato;
private String nome;
EstadoContrato(Contrato contrato, String nome){
this.nome = nome;
this.contrato = contrato;
}
public abstract EstadoContrato avanca();
public final Contrato getContrato() {
return contrato;
}
@Override
public String toString() {
return nome;
}
}
public class Novo extends EstadoContrato {
public Novo(Contrato contrato) {
super(contrato, "Novo");
}
@Override
public EstadoContrato avanca() {
return new EmAndamento(contrato);
}
}
public class EmAndamento extends EstadoContrato {
public EmAndamento(Contrato contrato) {
super(contrato, "EmAndamento");
}
@Override
public EstadoContrato avanca() {
return new Acertado(contrato);
}
}
public class Acertado extends EstadoContrato {
public Acertado(Contrato contrato) {
super(contrato, "Acertado");
}
@Override
public EstadoContrato avanca() {
return new Concluido(contrato);
}
}
public class ContratoMemento {
private List<EstadoContrato> estados = new ArrayList<>();
public void registra(EstadoContrato estado) {
estados.add(estado);
}
public Contrato get(int posicao) {
return estados.get(posicao).getContrato();
}
}
public class TestaContratos {
public static void main(String[] args) {
ContratoMemento historico = new ContratoMemento();
Contrato contrato = new Contrato(LocalDate.now(), "Jose");
historico.registra(contrato.salvaEstado());
System.out.println(contrato); //NOVO
contrato.avanca();
historico.registra(contrato.salvaEstado());
System.out.println(contrato); //EMANDAMENTO
contrato.avanca();
historico.registra(contrato.salvaEstado());
System.out.println(contrato); //ACERTADO
contrato.setData(LocalDate.of(2019, 12, 25));
contrato.avanca();
historico.registra(contrato.salvaEstado());
System.out.println(contrato); //CONCLUIDO
System.out.println("--------------------");
Contrato contratoAnterior = historico.get(0);
contratoAnterior.recuperar();
System.out.println(contratoAnterior); //NOVO
contratoAnterior = historico.get(3);
contratoAnterior.recuperar();
System.out.println(contratoAnterior); //Concluido
}
}