我写了一个类来为货币数据提供两个效用函数。它工作正常,但我想知道我是否能以任何方式改进它?我读到的是使用货币时应该使用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;
}
}
答案 0 :(得分:0)
我可以看到的改进是尝试使用工厂模式和多态性。
有一个名为: CurrencyFX 的界面 每种货币都有自己的类,例如:GBPCurrencyFX
然后让工厂返回您要计算的货币实例。请记住,每个类都将具有计算所需的所有变量。如果货币外汇汇率计算对所有货币都是通用的,您也可以同时拥有父抽象类。
这将遵循开放/封闭原则(避免if / else链),从而为您的应用程序提供可扩展性。
最后,你可以拥有如下所示的代码
CurrencyFX = CurrencyFXFacotry.getInstance("GBP");
BigDecimal eur= currencyFX.calculate();