用于存储货币汇率的设计

我开始了一个新的信用管理项目,我已经到了必须处理货币兑换的地步。(例如欧元 -> 美元)所以我进行了一些头脑风暴并得到了这个:

  • 货币是抽象的,每一种新货币都是一个接口的实现

  • 建立了一个汇率类,它存储了一个数组列表 pair<pair,double>(我在想像欧元、美元、1.14 这样的东西 -> 欧元兑美元的汇率是 1.14)并且有一些功能,比如:货币汇率存储,正确汇率的查找器(它是一个函数,它获取当前货币和新货币作为参数,并在列表中执行搜索,返回适当的货币)和一个确定货币对指数的效用函数。

现在,我正在考虑性能。我相信我的设计包含一些冗余:如果我有欧元对美元,我必须有美元对欧元。此外,对于更多条目(假设为 100k),我的存储(pair<pair,double> 的数组列表)的效率如何?我有哪些替代方案?我知道有很多数据结构,但我真的不知道该选择什么。

现在,对于代码:

转化率等级:

package currency;


import javafx.util.Pair;

import loggers.ILogger;


import java.util.ArrayList;


public class ConversionRates implements IConversionRate {

    private ArrayList<Pair<Pair<String, String>, Double>> conversionRates;

    private ILogger log;



    public ConversionRates(ArrayList<Pair<Pair<String, String>, Double>> conversionRates, ILogger log) {

        this.conversionRates = conversionRates;

        this.log = log;

    }


    @Override

    public double find(ICurrency firstCurrency, ICurrency secondCurrency) {

        log.add("Performing rate identification");

        String first = firstCurrency.getId();

        String second = secondCurrency.getId();

        int index = searchPairs(first, second);

        Pair<Pair<String, String>, Double> selectedPair = conversionRates.get(index);

        double rate = selectedPair.getValue();

        return rate;

    }


    private int searchPairs(String first, String second) {

        Pair<String, String> pairContainingRate = new Pair<>(first, second);

        for (int index = 0; index < conversionRates.size(); index++) {

            if (conversionRates.get(index).getKey().equals(pairContainingRate)) {

                log.add("Successfully found target " + first + "/" + second);

                return index;

            }

        }


        log.add("Failed to find target " + first + "/" + second);

        return -1;

    }


    @Override

    public void add(Pair<Pair<String, String>, Double> newRate) {

        log.add("Added new rate " + newRate);

        conversionRates.add(newRate);

    }


   


holdtom
浏览 193回答 2
2回答

蝴蝶不菲

我认为你应该开始更简单。我没有看到货币接口的原因,尤其是在这种情况下,因为我看不到您的实现将如何需要不同的提供者。每个Currency都由一个符号和一组该货币的汇率表示。public class Currency {&nbsp; &nbsp; private final String symbol;&nbsp;&nbsp; &nbsp; private final Set<ExchangeRate> rates = new HashSet<>();&nbsp; &nbsp; public Currency(String symbol) {&nbsp; &nbsp; &nbsp; &nbsp; this.symbol = symbol;&nbsp; &nbsp; }&nbsp; &nbsp; public BigDecimal convert(Currency currency, BigDecimal amount) {&nbsp; &nbsp; &nbsp; &nbsp; return findExchangeRate(currency).getRate().multiply(amount).setScale(2, RoundingMode.HALF_DOWN);&nbsp; &nbsp; }&nbsp; &nbsp; public String getSymbol() {&nbsp; &nbsp; &nbsp; &nbsp; return symbol;&nbsp; &nbsp; }&nbsp; &nbsp; public ExchangeRate findExchangeRate(Currency currency) {&nbsp; &nbsp; &nbsp; &nbsp; for(ExchangeRate rate: rates) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( rate.getCurrency().equals(currency)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return rate;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Currency not found: " + currency);&nbsp; &nbsp; }&nbsp; &nbsp; public void setExchangeRate(ExchangeRate rate) {&nbsp; &nbsp; &nbsp; &nbsp; if ( rates.contains(rate) ) rates.remove(rate);&nbsp; &nbsp; &nbsp; &nbsp; rates.add(rate);&nbsp; &nbsp; }&nbsp; &nbsp; public boolean removeExchangeRate(ExchangeRate rate) {&nbsp; &nbsp; &nbsp; &nbsp; return rates.remove(rate);&nbsp; &nbsp; }AnExchangeRate是所兑换货币的汇率,因此您无需每次都为该货币重复 1.0。不要忘记@Override hashCode,equals所以Set逻辑将正常工作。public class ExchangeRate {&nbsp; &nbsp; private final Currency currency;&nbsp; &nbsp; private final BigDecimal rate;&nbsp; &nbsp; public ExchangeRate(Currency currency, BigDecimal rate) {&nbsp; &nbsp; &nbsp; &nbsp; this.currency = currency;&nbsp; &nbsp; &nbsp; &nbsp; this.rate = rate;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public int hashCode() {&nbsp; &nbsp; &nbsp; &nbsp; final int prime = 31;&nbsp; &nbsp; &nbsp; &nbsp; int result = 1;&nbsp; &nbsp; &nbsp; &nbsp; result = prime * result + ((currency == null) ? 0 : currency.hashCode());&nbsp; &nbsp; &nbsp; &nbsp; return result;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean equals(Object obj) {&nbsp; &nbsp; &nbsp; &nbsp; if (this == obj)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; if (obj == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; if (getClass() != obj.getClass())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; ExchangeRate other = (ExchangeRate) obj;&nbsp; &nbsp; &nbsp; &nbsp; if (currency == null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (other.currency != null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; } else if (!currency.equals(other.currency))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; }使用它非常简单。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班级相同的事情。

qq_遁去的一_1

实际上,Kent Beck 在他关于 TDD 的书中就解决了这个问题。我没有读到最后,但我记得在某个时候他有Money抽象类,Sum(或类似的东西)用于存储金钱和Bank.&nbsp;银行负责汇率。我不知道,如果像创建类Dollar和Euro是一个不错的办法。也许只是坚持Money并保持货币在实例变量(KISS)中会更容易。我想我会想货币由一个类(完全处理Bank,ExchangeRate或什么最适合你),我会让Money情况不变。所有计算都是按Sum类进行的(或者其他什么,重点是将逻辑从货币本身移开)。不管怎样,也许你应该看看贝克的书。我很确定他设计得很好。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java