You are on page 1of 8

TAREFA COO 2017 - NMERO USP: 9844853 - Joo Lus Veronezzi Pacheco

O padro State um padro de projeto comportamental, utilizado quando o objeto deve se


comportar de uma determinada maneira de acordo com mudanas do seu estado interno.
Sua aplicao consiste na construo de uma classe abstrata de estado, que possa ser
implementada por vrias outras classes concretas de estado. O objeto em si, recebe uma
referncia para uma classe de estado (o que indica seu estado atual) e quando executar
alguma ao, ao invs de execut-la com decises prprias, delega esta tarefa para a
referncia do estado atual.
Para uma melhor aprendizagem, pretendo apresentar abaixo uma situao concreta que
ocorreu em meu atual trabalho, na qual identifiquei que, caso tivesse sido aplicado o padro
de projeto, teramos evitado uma srie de problemas futuros.
Imagine a classe Pedido, ela armazena uma referncia string para seu estado atual e possui
uma list de produtos adicionados, esta classe capaz de adicionar produtos, remover produtos
e faturar.
Quando o Pedido est em oramento, possvel adicionar e remover produtos bem como
fatur-lo(Implementao 1).
Se tivermos que adicionar o estado reserva, que ainda permite adicionar e remover produtos
mas garante que todos eles estejam reservados no banco de dados para que nenhum outro
vendedor possa adicion-los. teramos que ter uma funo nova para setar o status reserva e
vrias verificaes nas funes j existentes (Implementao 2).
Se tivermos de adicionar mais estados a lgica ficaria cada vez mais complexa, e se um
estado no puder seguir para outro especfico?
Para dar conta desse comportamento ento implantamos o padro State, que abstrair o
comportamento dos estados para classes especficas. Como uma boa prtica para este padro,
passamos o pedido como referncia para ele poder executar as aes que lhe so pertinentes.
Vamos aplicar o padro State para o pedido com seus trs estados(Oramento, Reserva e
Faturado) (Implementao 3);
Apesar do padro solicitar a construo de vrias classes uma para cada estado, ele permite
um alto controle interno do estado do objeto, delegando as aes para classes especficas, o
que permite maior manuteno do cdigo, uma vez que a as alteraes podem ser realizadas
localmente.
(assuma que todos os imports esto devidamente realizados, e que a classe produto est
devidamente construda)
Implementao 1
public class Pedido {
private String orcamento = "orcamento";
private String faturado = "faturado";
private String estadoAtual;
private int pedidoStatus;
private List<Produto> produtos;

public Pedido () {
this.produtos = new LinkedList<Produto>();
this.estadoAtual = this.orcamento;
}
public void addProduto(Produto produto) {
if (this.estadoAtual.equals(orcamento)) {
this.produtos.add(produto);
}
}
public void remodeProduto(Produto produto) {
if (this.estadoAtual.equals(orcamento)) {
this.produtos.remove(produto);
}
}
public void fatura () {
if (this.estadoAtual.equals(orcamento)) {
this.estadoAtual = this.faturado;
System.out.println("Imprime total e nota fiscal");
}
}
}
Implementao 2
public class Pedido {
private String orcamento = "orcamento";
private String reserva= "reserva";
private String faturado = "faturado";
private String estadoAtual;
private int pedidoStatus;
private List<Produto> produtos;

public Pedido () {
this.produtos = new LinkedList<Produto>();
this.estadoAtual = this.orcamento;
}
public void setReservado() {
this.estadoAtual = this.reservado;
for(Produto produto : produtos ) {
produto.isReservado(true);
}
}
public void addProduto(Produto produto) {
if (this.estadoAtual.equals(orcamento)) {
this.produtos.add(produto);
}
if (this.estadoAtual.equals(reserva)) {
produto.isReservado(true);
this.produtos.add(produto);
}
}
public void remodeProduto(Produto produto) {
if (this.estadoAtual.equals(orcamento)) {
this.produtos.remove(produto);
}
if (this.estadoAtual.equals(reserva)) {
produto.isReservado(false);
this.produtos.remove(produto);
}
}
public void fatura () {
if (this.estadoAtual.equals(orcamento) | | this.estadoAtual.equals(reserva)) {
this.estadoAtual = this.faturado;
System.out.println("Imprime total e nota fiscal");
}
}
}
Implementao 3
public interface PedidoComportamento {
public void addProduto(Produto produto);
public void removeProduto(Produto produto);
public void fatura();
}
public abstract class PedidoEstado implements PedidoComportamento {
private Pedido pedido;
public PedidoEstado(Pedido pedido) {
this.pedido = pedido;
}
public Pedido getPedido() {
return this.pedido;
}
@Override
public abstract void addProduto(Produto produto);
@Override
public abstract void removeProduto(Produto produto);
@Override
public abstract void fatura();
}

public class Orcamento extends PedidoEstado {


public Orcamento(Pedido pedido) {
super(pedido);
}
@Override
public void addProduto(Produto produto) {
super.getPedido().getProdutos().add(produto);
}
@Override
public void removeProduto(Produto produto) {
super.getPedido().getProdutos().remove(produto);
}
@Override
public void fatura() {
System.out.println("Imprime valor total e Emite Nota Fiscal");
super.getPedido().setEstado(new Faturado(super.getPedido()));
}
}

public class Reserva extends PedidoEstado{


public Reserva(Pedido pedido) {
super(pedido);
for(Produto produto : pedido.getProdutos()) {
produto.isReservado(true);
}
}
@Override
public void addProduto(Produto produto) {
produto.isReservado(true);
super.getPedido().getProdutos().add(produto);
}
@Override
public void removeProduto(Produto produto) {
produto.isReservado(false);
super.getPedido().getProdutos().remove(produto);
}
@Override
public void fatura() {
System.out.println("Imprime valor total e Emite Nota Fiscal");
super.getPedido().setEstado(new Faturado(super.getPedido()));
}
}

public class Faturado extends PedidoEstado {


public Faturado(Pedido pedido) {
super(pedido);
}
@Override
public void addProduto(Produto produto) {
System.out.println("Impossivel adicionar um produto a um pedido j
faturado");
}
@Override
public void removeProduto(Produto produto) {
System.out.println("Impossivel remover um produto de um pedido j
faturado");
}
@Override
public void fatura() {
System.out.println("Pedido j faturado");
}
}

public class Pedido implements PedidoComportamento {


private PedidoEstado estadoAtual;
private int pedidoStatus;
private List<Produto> produtos;

public Pedido () {
this.produtos = new LinkedList<Produto>();
this.estadoAtual = new Orcamento(this);
}
public List <Produto> getProdutos() {
return this.produtos;
}

public void setEstado(PedidoEstado estado) {


this.estadoAtual = estado;
}

public void addProduto(Produto produto) {


this.estadoAtual.addProduto(produto);
}

public void removeProduto(Produto produto) {


this.estadoAtual.removeProduto(produto);
}

public void fatura () {


this.estadoAtual.fatura();
}
}

You might also like