Ybadoo - Soluções em Software Livre
Tutoriais
Programação Orientada a Objetos

Desenvolva um programa que simule uma máquina de vendas automática, utilizando o padrão de projeto Chain of Responsibility como base.

A máquina possui diversos slots, cada um capaz de receber um tipo de moeda diferente: R$ 0,01, R$ 0,05, R$ 0,10, R$ 0,25, R$ 0,50 e R$ 1,00.

A máquina deve receber moedas e delegar aos slots que capturem-nas.

Quando chegar ao valor do produto desejado, a máquina deve entregar o produto e informar o troco, caso houver.

 

Arquivo Coin.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
 *
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.3
 * or any later version published by the Free Software Foundation; with
 * no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

/**
 * Helper
 */
public enum Coin
{
  ONE_PENCE,         // R$ 0,01
  FIVE_PENCE,        // R$ 0,05
  TEN_PENCE,         // R$ 0,10
  TWENTY_FIVE_PENCE, // R$ 0,25
  FIFTY_PENCE,       // R$ 0,50
  ONE_POUND;         // R$ 1,00
}

Arquivo CoinHandler.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
 *
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.3
 * or any later version published by the Free Software Foundation; with
 * no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

import java.math.BigDecimal;

/**
 * Handler
 */
public abstract class CoinHandler
{
  /**
   * Proximo slot da ATM
   */
  protected CoinHandler successor;
  
  /**
   * Reconhecer o valor monetario da moeda
   * 
   * @param coin moeda a ser analisada
   * @return valor monetario da moeda
   */
  public abstract BigDecimal recognize(Coin coin);

  /**
   * Configurar o proximo slot
   * 
   * @param successor proximo slot
   */
  public void setSuccessor(CoinHandler successor)
  {
    this.successor = successor;
  }
}

Arquivo OnePenceHandler.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
 *
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.3
 * or any later version published by the Free Software Foundation; with
 * no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

import java.math.BigDecimal;

/**
 * Concrete Handler (R$ 0,01)
 */
public class OnePenceHandler extends CoinHandler
{
  /* (non-Javadoc)
   * @see com.ybadoo.tutoriais.poo.CoinHandler#recognize(com.ybadoo.tutoriais.poo.Coin)
   */
  public BigDecimal recognize(Coin coin)
  {
    if(Coin.ONE_PENCE.equals(coin))
    {
      System.out.println("Reconhecido R$ 0,01");
      
      return new BigDecimal(0.01);
    }
    else if(successor != null)
    {
      return successor.recognize(coin);
    }
    else
    {
      return new BigDecimal(0.0);
    }
  }
}

Arquivo FivePenceHandler.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
 *
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.3
 * or any later version published by the Free Software Foundation; with
 * no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

import java.math.BigDecimal;

/**
 * Concrete Handler (R$ 0,05)
 */
public class FivePenceHandler extends CoinHandler
{
  /* (non-Javadoc)
   * @see com.ybadoo.tutoriais.poo.CoinHandler#recognize(com.ybadoo.tutoriais.poo.Coin)
   */
  public BigDecimal recognize(Coin coin)
  {
    if(Coin.FIVE_PENCE.equals(coin))
    {
      System.out.println("Reconhecido R$ 0,05");
      
      return new BigDecimal(0.05);
    }
    else if(successor != null)
    {
      return successor.recognize(coin);
    }
    else
    {
      return new BigDecimal(0.0);
    }
  }
}

Arquivo TenPenceHandler.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
 *
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.3
 * or any later version published by the Free Software Foundation; with
 * no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

import java.math.BigDecimal;

/**
 * Concrete Handler (R$ 0,10)
 */
public class TenPenceHandler extends CoinHandler
{
  /* (non-Javadoc)
   * @see com.ybadoo.tutoriais.poo.CoinHandler#recognize(com.ybadoo.tutoriais.poo.Coin)
   */
  public BigDecimal recognize(Coin coin)
  {
    if(Coin.TEN_PENCE.equals(coin))
    {
      System.out.println("Reconhecido R$ 0,10");
      
      return new BigDecimal(0.10);
    }
    else if(successor != null)
    {
      return successor.recognize(coin);
    }
    else
    {
      return new BigDecimal(0.0);
    }
  }
}

Arquivo TwentyFivePenceHandler.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
 *
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.3
 * or any later version published by the Free Software Foundation; with
 * no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

import java.math.BigDecimal;

/**
 * Concrete Handler (R$ 0,25)
 */
public class TwentyFivePenceHandler extends CoinHandler
{
  /* (non-Javadoc)
   * @see com.ybadoo.tutoriais.poo.CoinHandler#recognize(com.ybadoo.tutoriais.poo.Coin)
   */
  public BigDecimal recognize(Coin coin)
  {
    if(Coin.TWENTY_FIVE_PENCE.equals(coin))
    {
      System.out.println("Reconhecido R$ 0,25");
      
      return new BigDecimal(0.25);
    }
    else if(successor != null)
    {
      return successor.recognize(coin);
    }
    else
    {
      return new BigDecimal(0.0);
    }
  }
}

Arquivo FiftyPenceHandler.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
 *
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.3
 * or any later version published by the Free Software Foundation; with
 * no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

import java.math.BigDecimal;

/**
 * Concrete Handler (R$ 0,50)
 */
public class FiftyPenceHandler extends CoinHandler
{
  /* (non-Javadoc)
   * @see com.ybadoo.tutoriais.poo.CoinHandler#recognize(com.ybadoo.tutoriais.poo.Coin)
   */
  public BigDecimal recognize(Coin coin)
  {
    if(Coin.FIFTY_PENCE.equals(coin))
    {
      System.out.println("Reconhecido R$ 0,50");
      
      return new BigDecimal(0.50);
    }
    else if(successor != null)
    {
      return successor.recognize(coin);
    }
    else
    {
      return new BigDecimal(0.0);
    }
  }
}

Arquivo OnePoundHandler.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
 *
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.3
 * or any later version published by the Free Software Foundation; with
 * no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

import java.math.BigDecimal;

/**
 * Concrete Handler (R$ 1,00)
 */
public class OnePoundHandler extends CoinHandler
{
  /* (non-Javadoc)
   * @see com.ybadoo.tutoriais.poo.CoinHandler#recognize(com.ybadoo.tutoriais.poo.Coin)
   */
  public BigDecimal recognize(Coin coin)
  {
    if(Coin.ONE_POUND.equals(coin))
    {
      System.out.println("Reconhecido R$ 1,00");
      
      return new BigDecimal(1.0);
    }
    else if(successor != null)
    {
      return successor.recognize(coin);
    }
    else
    {
      return new BigDecimal(0.0);
    }
  }
}

Arquivo ATM.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
 *
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.3
 * or any later version published by the Free Software Foundation; with
 * no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Locale;

/**
 * Automated Teller Machine (ATM)
 */
public class ATM
{
  /**
   * Preco a ser cobrado pela ATM
   */
  private BigDecimal price;
  
  /**
   * Primeiro slot da ATM
   */
  private CoinHandler slot;
  
  /**
   * Valor depositado na ATM pelo usuario
   */
  private BigDecimal total;
  
  /**
   * Construtor para inicializar o preco a ser cobrado pela ATM
   * 
   * @param price preco a ser cobrado pela ATM
   */
  public ATM(BigDecimal price)
  {
    this.price = price;
    
    total = new BigDecimal(0.0);
    
    NumberFormat nf = NumberFormat.getInstance(new Locale("pt", "BR"));
    
    System.out.println("Preço a ser cobrado: R$ " + nf.format(price));
    
    slot = new OnePenceHandler();
    CoinHandler fivePence = new FivePenceHandler();
    CoinHandler tenPence = new TenPenceHandler();
    CoinHandler twentyFivePence = new TwentyFivePenceHandler();
    CoinHandler fiftyPence = new FiftyPenceHandler();
    CoinHandler onePound = new OnePoundHandler();
    
    slot.setSuccessor(fivePence);
    fivePence.setSuccessor(tenPence);
    tenPence.setSuccessor(twentyFivePence);
    twentyFivePence.setSuccessor(fiftyPence);
    fiftyPence.setSuccessor(onePound);
  }
  
  /**
   * Depositar uma moeda
   * 
   * @param coin moeda depositada pelo usuario na ATM
   */
  public void deposit(Coin coin)
  {
    total = total.add(slot.recognize(coin));
    
    NumberFormat nf = NumberFormat.getInstance(new Locale("pt", "BR"));

    if(total.doubleValue() < price.doubleValue())
    {
      System.out.println("Falta R$ " + nf.format(price.subtract(total)));
    }
    else if(total.doubleValue() == price.doubleValue())
    {
      System.out.println("Obrigado pela sua preferência!");
    }
    else if(total.doubleValue() > price.doubleValue())
    {
      System.out.println("Obrigado pela sua preferência!");
      System.out.println("Seu troco á de R$ " + nf.format(total.subtract(price)));
    }
  }
}

Arquivo Application.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
 *
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.3
 * or any later version published by the Free Software Foundation; with
 * no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

import java.math.BigDecimal;

/**
 * Teste da aplicacao
 */
public class Application
{
  /**
   * Metodo principal da linguagem de programacao Java
   * 
   * @param args argumentos da linha de comando (nao utilizado)
   */
  public static void main(String[] args)
  {
    // Preço a ser cobrado: R$ 2,02
    ATM atm = new ATM(new BigDecimal(2.02));
    
    // Reconhecido R$ 1,00
    // Falta R$ 1,02
    atm.deposit(Coin.ONE_POUND);
    
    // Reconhecido R$ 0,50
    // Falta R$ 0,52
    atm.deposit(Coin.FIFTY_PENCE);
    
    // Reconhecido R$ 0,25
    // Falta R$ 0,27
    atm.deposit(Coin.TWENTY_FIVE_PENCE);
    
    // Reconhecido R$ 0,10
    // Falta R$ 0,17
    atm.deposit(Coin.TEN_PENCE);
    
    // Reconhecido R$ 0,10
    // Falta R$ 0,07
    atm.deposit(Coin.TEN_PENCE);
    
    // Reconhecido R$ 0,05
    // Falta R$ 0,02
    atm.deposit(Coin.FIVE_PENCE);
    
    // Reconhecido R$ 0,01
    // Falta R$ 0,01
    atm.deposit(Coin.ONE_PENCE);
    
    // Reconhecido R$ 0,01
    // Obrigado pela sua preferência!
    atm.deposit(Coin.ONE_PENCE);
  }
}