使用汇率转换货币

时间:2014-12-11 11:45:11

标签: java concurrency bigdecimal

我写了一个类来为货币数据提供两个效用函数。它工作正常,但我想知道我是否能以任何方式改进它?我读到的是使用货币时应该使用BigDecimal,因为精度是imiport。

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 -> USD  = 1.654
    CHF -> USD  = 1.10
    EUR -> 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<CompanyData> 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;
    }
}

}


**更新 - **在建议使用工厂模式之后,这就是它的外观。

CurrencyFX

public interface CurrencyFX {

BigDecimal usd_factor = new BigDecimal("1.35");     //static final variable available in all
                                                    //implementations
BigDecimal convertCurrencyToEUR(BigDecimal inValue) throws ArithmeticException;

}

GBPCurrencyFX

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;
}

}

CurrencyFXFactory

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;
   }

}

1 个答案:

答案 0 :(得分:0)

我可以看到的改进是尝试使用工厂模式和多态性。

有一个名为: CurrencyFX 的界面 每种货币都有自己的类,例如:GBPCurrencyFX

然后让工厂返回您要计算的货币实例。请记住,每个类都将具有计算所需的所有变量。如果货币外汇汇率计算对所有货币都是通用的,您也可以同时拥有父抽象类。

这将遵循开放/封闭原则(避免if / else链),从而为您的应用程序提供可扩展性。

最后,你可以拥有如下所示的代码

CurrencyFX = CurrencyFXFacotry.getInstance("GBP");
BigDecimal eur= currencyFX.calculate();