0

I am using a web service to get currency rates for 4 different currencies. What I am doing so far is to get these rates and store then in a 4x4 matrix in a way that any value can be easily retrieved without having to use the web service everytime.

What I want to know is what is the best approach, using design patterns (and which one would be more appropriate) to set and get the values of this matrix. I am currently just using something like this:

public void setPoundToEuro(float value) {
    currencyMatrix[0][1] = value;
}

public float getPoundToEuro() {
    return currencyMatrix[0][1];
}

What I was hoping is to have something more abstract to whichever class needs to use this service and get these values. Something like another class calling a method just sending two Strings and the same method would return any currency rates, depending on the Strings received. In this case it would be "pound" and "euro".

I hope to have made myself clear, but if not, please let me know. I have not seen much questions like this here, so I hope this is not a problem, I am trying to discuss and find the best approach for my problem. I have already seen this design patterns for currency conversion? and it did help clarify somethings for me, but the situation is slightly different, so I thought it was reasonable to ask a new question.

Community
  • 1
  • 1
Larissa Leite
  • 1,358
  • 3
  • 21
  • 36
  • 1
    Use a Map where the key is a class with both the FromCurrency and ToCurrency, and the value is a BigDecimal with the conversion rate. Make sure you override `equals()` and `hashCode()` in the class you are going to use as a key. – Marcelo Sep 25 '13 at 17:19
  • Thanks for you comment, Marcelo. That seems feasible, but I was hoping for a design pattern kind of approach. Anyway, could you provide a more concrete example of your idea? – Larissa Leite Sep 25 '13 at 17:23
  • 1
    I'm sure this is a school project, but it is, most likely, in your best interest [not to use floats or doubles for currency](http://stackoverflow.com/q/3730019/42962). – hooknc Sep 25 '13 at 18:05
  • Thanks for the advice, but this is definitely not a school project. – Larissa Leite Sep 25 '13 at 18:10

2 Answers2

1

Not exactly rocket science, still needs additional checks when converting, if the rates have not yet been defined and has room for improvements, but I believe it's a bit more object oriented and you get the picture.

If you were to follow Marcelo's suggestion with dedicated converters, the currencyCache could be a Map<String, Converter> and the convert method something like currencyCache.get(from+to).calculate(amount)

public class CurrencyConverter {
    static Map<String, Map<String, Double>> currencyCache = new HashMap<>();

    static {
        for (ConversionDefinition definition : ConversionDefinition.values()) {
            Map<String, Double> rates = currencyCache.get(definition.from);

            if (rates == null) {
                rates = new HashMap<>();
                currencyCache.put(definition.from, rates);
            }

            rates.put(definition.to, definition.rate);
        }
    }

    public static Double convert(String from, String to, Double amount) {
        return currencyCache.get(from).get(to) * amount;
    }

    public enum ConversionDefinition {
        EURO_TO_USD("euro", "usd", 10d),
        USD_TO_EUR("usd", "euro", 1 / 10d);

        private final String from;
        private final String to;
        private final Double rate;

        ConversionDefinition(String from, String to, Double rate) {
            this.from = from;
            this.to = to;
            this.rate = rate;
        }
    }
}
Morfic
  • 15,178
  • 3
  • 51
  • 61
  • Also please excuse the use of double. I was merely trying to express an idea – Morfic Sep 25 '13 at 18:13
  • I wouldn't use an enum for that: there are hundreds of currencies, giving thousands of possible combinations and the rate is not constant... – assylias Sep 25 '13 at 18:25
  • I agree with you on that, and if that should be the case then she may need a different, more flexible, mechanism of defining the conversion rules. But given that she has only a few currencies, 4 atm, I thought this to be rather straight-forward. – Morfic Sep 25 '13 at 18:31
  • Perhaps the cache could be loaded from a set property files for each currency, which contain as key the destination currency, and for value the rate... – Morfic Sep 25 '13 at 19:41
0

I apprectiate a lot all of the suggestions given. Thanks to them I've come up with a very simple solution myself, using HashMap.

I have created a class that is basically the following:

private Map currencyMap;

public CurrencyData() {
    currencyMap = new HashMap();
}

public void setCurrencyValue(String key, String value) {
    currencyMap.put(key, value);
}

public String getCurrencyValue(String key) {
    return currencyMap.get(key).toString();
}

And on my Main class, as the program initializes, I simply use the web service to fill in the hash map by calling the method setCurrencyValue.

If anyone spots any flaws on this current approach, please let me know, I am still open to suggestions.

Larissa Leite
  • 1,358
  • 3
  • 21
  • 36
  • 1
    Well, I totally missed your point... You are actually querying a WS and want to cache the result in your application. If you could explain a normal flow, perhaps we can give you some additional advice, but so far it looks ok – Morfic Sep 25 '13 at 20:12
  • 1
    That looks reasonable. – assylias Sep 25 '13 at 21:31