Win a copy of Kotlin in Action this week in the Kotlin forum!
programming forums Java Java JSRs Mobile Certification Databases Caching Books Engineering Languages Frameworks Products This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
Sheriffs:
Saloon Keepers:
Bartenders:

# Looking for a Conversion Pattern

Lou Pelagalli
Ranch Hand
Posts: 150
1
Hi,

I'm creating a new conversion application that will convert one sort of measurement to another, for example mile to kilometers and back, gallons to litres and back, and inches to centimeters and back, and many others.

I've be trying without success to find a pattern to do this without having to check each from and to conversion input to yeild a result.

Any suggestions?

Thanks,

Lou

Anurag Verma
Ranch Hand
Posts: 170
you can have a map which contains the combination of conversion types as key & the relevant converter Class as value, from UI take the from & to conversion types, concat them, get the converter from map, & calculate the result. No "if" will be needed.

Lou Pelagalli
Ranch Hand
Posts: 150
1
Thank you Anurag, that's a good idea.

Richard Tookey
Bartender
Posts: 1166
17
I did this several years ago for a client. The number of possible conversions makes it impractical to have a converter for every possible conversion for a given unit so the technique that I and many others used was to have a central set of units (MKS is standard) and then each converter has a method to convert to the central unit and a method to convert from the central unit. any conversion is then a two stage process of converting first to the central unit and then form the central unit to the target using. For example, the conversion of leagues to inches first converts leagues to meters and then the meters to inches.

Lou Pelagalli
Ranch Hand
Posts: 150
1
Thanks Richard, great minds think alike! I was already thinking along those lines

Kelvin = Celsius = Fahrenheit
or
Fahrenheit = Celsius = Kelvin

where Celsius would be the standard intermediate unit (I called it the base) for all temperature conversions where Celsius wasn't already part of the conversion.

I didn't know there was a standard, MKS, but I did some reading about it at http://en.wikipedia.org/wiki/MKS_system_of_units and http://en.wikipedia.org/wiki/International_System_of_Units.

Thank you for that information.

I'm thinking I may be able to keep it even smaller by using generic math terms. Then I can use an Abstract class where all subclasses will be named after the measurement.

The Abstract class would have Abstract methods like getMultiplicand().

Class Fahrenheit would return the UI value in Celsius in getMultiplicand(). Class Kelvin would be responsible for knowing the multiplier to convert Celsius from Object fahrenheit.getMultiplicand(). Then getMultiplicand() can be used for any unit of measure.

Richard Tookey
Bartender
Posts: 1166
17
You might keep it smaller by using your getMultiplicand() and such methods but that will make it difficult for the user. My memory is of there being an interface with just two primary methods

which made it very easy for the user; a prime requirement in my case.

Though most are, you can't rely on the transformations being linear (Decibels are a prime example) so you can't use the getMultiplicand() approach for all units. Initially I also made the converters accessible only through a Map using a type safe enumeration as key (I implemented this well before the Java 'enum' was introduced) but later after discussions with the users of the library the enumeration key was replaced by a simple String key so that the whole conversion could be loaded from an XML file. All the converters were thread safe (very easy for this application) so a singleton was used to lookup a converter by name.

I can't remember exactly how many explicit classes there were but not more than 8 but there were over 200 converters in the Map.

Lou Pelagalli
Ranch Hand
Posts: 150
1
Thank you Richard!

One last question please. I had thought that this would be a perfect opportunity to use subclasses, with Measurements being an super class, abstract or not, and the conversions as subclasses for example Fahrenheit, Celsius, Yards, meters, etc.

Can you recall and tell me why you chose to use an interface?

Thanks,

Lou

Richard Tookey
Bartender
Posts: 1166
17
Lou Pellegrini wrote:
Can you recall and tell me why you chose to use an interface?

Since the users of the library looked up the converter through a singleton and didn't need anything but the two methods declared in the interface the user did not need to know anything else. Behind the scenes I did have several (I seem to remember just 3 - linear, logarithmic and non-linear via interpolation) converter classes that implemented the interface but there was never any need for the user to know the detail about these classes. When a user looked up a particular converter he/she didn't care how it was implemented. A sound principle of Java (and other OO languages) is to program to an interface. As long as one continues to meet the contract specification defined by the interface one can change the implementation without affecting the users.

Note - the non-linear converters were table driven using linear interpolation with the interpolation coefficients specified in the XML file.

 Consider Paul's rocket mass heater.