title: Converting currency using exchange rate
body: <p>I have written a class to provide two utility functions on Monetary data. It is workingn fine but I would like to know if i can improve it any way? What I read was BigDecimal should be used when working with currency as precision is imiport.</p>
  
  <pre><code>public class Money {
  
  /**
   * @param Currency type
   * @param Amount to convert
   * @return BigDecimal Converted currency in Euros (EUR) 
   */
  public static BigDecimal convertCurrencyToEUR(BigDecimal inValue, String inCurrency) {
      /*Exchange Rates:
      GBP -&gt; USD  = 1.654
      CHF -&gt; USD  = 1.10
      EUR -&gt; USD  = 1.35
      GBP = 1.654/1.35 EUR
      CHF = 1.10/1.35 EUR*/
  
      try{
          BigDecimal usd_factor = new BigDecimal("1.35");
          BigDecimal gbp_factor = new BigDecimal("1.654");
          BigDecimal chf_factor = new BigDecimal("1.10");
  
          BigDecimal gbp_eur_rate = gbp_factor.divide(usd_factor, 5, BigDecimal.ROUND_HALF_UP);
          BigDecimal chf_eur_rate = chf_factor.divide(usd_factor, 5, BigDecimal.ROUND_HALF_UP);
  
  
          if(inCurrency.equalsIgnoreCase("GBP")){
              BigDecimal eur = inValue.multiply(gbp_eur_rate);
              eur = eur.setScale(5, BigDecimal.ROUND_HALF_UP);
              return eur;
  
          } else if (inCurrency.equalsIgnoreCase("CHF")) {
              BigDecimal eur = inValue.multiply(chf_eur_rate);
              eur = eur.setScale(5, BigDecimal.ROUND_HALF_UP);
              return eur;
          } else {
              System.out.println("Unhandled Currency");
              return null;
          }
      }catch(ArithmeticException e){
          System.out.println("Arithmetic exception occoured: "+e);
          return null;
      }
  }
  
  /**
   * @param companyDataList
   * @return BigDecimal Average amount in Euros (EUR) 
   */
  public static BigDecimal calculateAverageAmount(List&lt;CompanyData&gt; companyDataList) {
      try{
          BigDecimal result = new BigDecimal("0");
  
          for (CompanyData companyData : companyDataList) {
              result = result.add(companyData.getAmount());
          }
          result = result.divide(new BigDecimal(companyDataList.size()+""), 2, BigDecimal.ROUND_HALF_UP);
          return result;
  
      }catch(ArithmeticException e){
          System.out.println("Arithmetic exception occoured: "+e);
          return null;
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <hr>
  
  <p>**Update - ** After a suggestion to use a factory pattern this is how it looks.</p>
  
  <p><strong>CurrencyFX</strong></p>
  
  <pre><code>public interface CurrencyFX {
  
  BigDecimal usd_factor = new BigDecimal("1.35");     //static final variable available in all
                                                      //implementations
  BigDecimal convertCurrencyToEUR(BigDecimal inValue) throws ArithmeticException;
  </code></pre>
  
  <p>}</p>
  
  <p><strong>GBPCurrencyFX</strong></p>
  
  <pre><code>public class GBPCurrencyFX implements CurrencyFX{
  
  @Override
  public BigDecimal convertCurrencyToEUR(BigDecimal inValue) {
      BigDecimal gbp_factor = new BigDecimal("1.654");
      BigDecimal gbp_eur_rate = gbp_factor.divide(usd_factor, 10, BigDecimal.ROUND_HALF_UP);
  
      BigDecimal eur = inValue.multiply(gbp_eur_rate);
      eur = eur.setScale(5, BigDecimal.ROUND_HALF_UP);
      return eur;
  }
  </code></pre>
  
  <p>}</p>
  
  <p><strong>CurrencyFXFactory</strong></p>
  
  <pre><code>public class CurrencyFXFactory {
  //use getInstance method to get object of type CurrencyFX 
     public static CurrencyFX getInstance(String currency){
        if(currency == null){
           return null;
        }     
        if(currency.equalsIgnoreCase("GBP")){
           return new GBPCurrencyFX();
        } else if(currency.equalsIgnoreCase("CHF")){
           return new CHFCurrencyFX();
        } 
        return null;
     }
  </code></pre>
  
  <p>}</p>