2 回答
TA贡献1810条经验 获得超4个赞
我认为你应该开始更简单。我没有看到货币接口的原因,尤其是在这种情况下,因为我看不到您的实现将如何需要不同的提供者。每个Currency都由一个符号和一组该货币的汇率表示。
public class Currency {
private final String symbol;
private final Set<ExchangeRate> rates = new HashSet<>();
public Currency(String symbol) {
this.symbol = symbol;
}
public BigDecimal convert(Currency currency, BigDecimal amount) {
return findExchangeRate(currency).getRate().multiply(amount).setScale(2, RoundingMode.HALF_DOWN);
}
public String getSymbol() {
return symbol;
}
public ExchangeRate findExchangeRate(Currency currency) {
for(ExchangeRate rate: rates) {
if ( rate.getCurrency().equals(currency)) {
return rate;
}
}
throw new IllegalArgumentException("Currency not found: " + currency);
}
public void setExchangeRate(ExchangeRate rate) {
if ( rates.contains(rate) ) rates.remove(rate);
rates.add(rate);
}
public boolean removeExchangeRate(ExchangeRate rate) {
return rates.remove(rate);
}
AnExchangeRate是所兑换货币的汇率,因此您无需每次都为该货币重复 1.0。不要忘记@Override hashCode,equals所以Set逻辑将正常工作。
public class ExchangeRate {
private final Currency currency;
private final BigDecimal rate;
public ExchangeRate(Currency currency, BigDecimal rate) {
this.currency = currency;
this.rate = rate;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((currency == null) ? 0 : currency.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ExchangeRate other = (ExchangeRate) obj;
if (currency == null) {
if (other.currency != null)
return false;
} else if (!currency.equals(other.currency))
return false;
return true;
}
使用它非常简单。
Currency usd = new Currency("USD");
Currency eur = new Currency("EUR");
usd.setExchangeRate(new ExchangeRate(eur, new BigDecimal("0.87540")));
eur.setExchangeRate(new ExchangeRate(usd, new BigDecimal("1.14233")));
BigDecimal myMoney = new BigDecimal("1000.00");
myMoney = usd.convert(eur, myMoney);
System.out.println("My Euros: " + myMoney);
myMoney = eur.convert(usd, myMoney);
System.out.println("My Dollars: " + myMoney);
注意 的用法BigDecimal。由于浮点数和双精度数的准确性失败,这种或类似的东西对于货币计算总是必要的。您可以转换为LongorInteger并自己跟踪比例,但您将做与BigDecimal班级相同的事情。
TA贡献1725条经验 获得超7个赞
实际上,Kent Beck 在他关于 TDD 的书中就解决了这个问题。
我没有读到最后,但我记得在某个时候他有Money
抽象类,Sum
(或类似的东西)用于存储金钱和Bank
. 银行负责汇率。
我不知道,如果像创建类Dollar
和Euro
是一个不错的办法。也许只是坚持Money
并保持货币在实例变量(KISS)中会更容易。我想我会想货币由一个类(完全处理Bank
,ExchangeRate
或什么最适合你),我会让Money
情况不变。所有计算都是按Sum
类进行的(或者其他什么,重点是将逻辑从货币本身移开)。
不管怎样,也许你应该看看贝克的书。我很确定他设计得很好。
添加回答
举报