Currency Exchange Factory
An instance of an RWExchangeFactory contains an exchange rate table and at least one exchange group. Exchange groups can construct the exchange objects that are used to perform currency conversions. When presented with a source/target currency pair, the exchange factory searches its list of exchange groups until it finds one that can create an exchange object with the given source/target pair and the factory's associated exchange rate table. If none of the groups in the factory can create a valid exchange object, the factory returns an invalid object.
The following example demonstrates how a factory works.
Suppose you have the job of exchanging currency. You have at your disposal a currency exchange rate table, a calculator, and lots of currencies. You also have the following procedure for doing currency conversion:
1. First, you always check to see if both the source and target currencies are in the European Monetary Union (EMU). If so, you need to use the following rule for converting the source amount into a target:
a. Find a conversion factor in the exchange rate table for converting Euro's into the source currency (usually in the form 1 Euro = source).
b. Convert the source amount into a Euro amount by dividing by this factor.
c. Find a conversion factor for converting Euro's to the target currency.
d. Use this factor to multiply the amount just computed to obtain the amount in the target currency.
2. If either one or both currencies are not part of the EMU, you will look for an exchange rate that converts the source amount to the target amount. Once you find that rate, you can multiply the source amount by this exchange rate to obtain the target currency amount.
3. If you can't find a source-to-target rate in the exchange rate table, look in the table for an exchange rate that converts the target into the source. If you find this rate, divide the source amount by it to obtain the amount in the target currency.
Class RWExchangeFactory encapsulates this behavior. An RWExchangeFactory instance contains an exchange rate table and a list of one or more currency exchange groups. As mentioned in Currency Exchange Groups, currency exchange groups produce an exchange object with a particular implementation when presented with a source currency, a target currency, and an exchange rate table. The Currency Module supplies the following exchange groups:
*RWEuroGroup, which produces an exchange object with an implementation that performs an exchange using the triangulating procedure described in step one of the example.
*RWMultiplicationGroup, which creates exchange objects that implement the exchange algorithm described in step two.
*RWDivisionGroup, which creates exchange objects that implement the exchange algorithm described in step three.
The exchange groups listed above are derived from the abstract base class RWExchangeGroupImpl. The handle class, RWExchangeGroup presents the interface common to all exchange groups and contains a pointer to a specific implementation class that must be derived from RWExchangeGroupImpl. An exchange factory object, RWExchangeFactory, contains a list of exchange group objects.
When you create a factory, you are defining the overall process that will be used to do a conversion. In order to implement the scenario described at the beginning of this section, your exchange rate factory needs to contain an exchange rate table and three RWExchangeGroup objects. The first RWExchangeGroup object in the factory contains an RWEuroGroup implementation, the second contains an RWMultiplicationGroup implementation, and the third contains an RWDivisionGroup implementation. The code for creating such a factory looks something like this:
 
RWExchangeRateTable rates; // Exchange rates
.
.
.
RWTValSlist<RWCString> euroCurrencies // mnemonics of
// currencies in the EMU
.
.
.
// Create the exchange rate factory that uses the exchange
// rate table rates. By default it contains
// a single exchange group instance, which uses an
// RWMultiplicationGroup implementation.
 
RWExchangeFactory<double> exchangeFactory(rates);
 
// Create and prepend the Euro exchange group. This puts the
// Euro group at the head of the list and the multiplication
// group in the second position.
RWEuroGroup<double>* euroGroupImpl =
new RWEuroGroup<double>(euroCurrencies);
exchangeFactory.prependExchangeGroup(
RWExchangeGroup(euroGroupImpl) );
 
// Next create a division exchange group and append it
// to the list.
 
RWDivisionGroup<double>* divGroupImpl =
new RWDivisionGroup<double>(euroCurrencies);
 
exchangeFactory.appendExchangeGroup(
RWExchangeGroup(divGroupImpl) );
Now, suppose that you want to create a simpler factory for an application that you know will not perform any triangular conversions, but may use either a multiplication or a division style of conversion. The following code sets up that factory:
 
RWExchangeRateTable rates; // Exchange rates
.
.
.
// Create the exchange rate factory that uses the exchange
// rate table rates. By default it contains
// a single exchange group instance, which uses an
// RWMultiplicationGroup implementation.
 
RWExchangeFactory<double> exchangeFactory(rates);
 
// Create a division exchange group and append it
// to the list.
 
RWDivisionGroup<double>* divGroupImpl =
new RWDivisionGroup<double>;
 
exchangeFactory.appendExchangeGroup(
RWExchangeGroup(divGroupImpl) );