# What is the accepted practice for handling numeric conversions under OOP?

I am making a weather app that involves temperatures. You can change between Kelvin, Celsius, and Fahrenheit just for fun.

However, temperature figures get used all over the place in different ways. Does it make sense to have a Temperature class that stores the number as well as its units, and has various methods for internally converting it to some other unit of measurement, so I am not performing conversion math all over the place?

What is the accepted practice for storing its current state? A String? If currentUnits is "Fahrenheit" then do this, etc. Is there a better way to store these using enums or constants somehow?

Just trying to get a feel for the best practices here.

``````public class Weight {
private double mWeight; // assumed to be in lbs

public Weight(double weight) {
mWeight = weight;
}

public double getWeight(Context context) {
AppSettings appsettings = new AppSettings(context);
if (appsettings.getUnitsPref().equals("kgs")){
mWeight *= 2.20462;
}
return mWeight;
}

}
``````

Best practice would be anything which reasonably satisfies the DRY Principle. In this case, you certainly don't want to be duplicating the same conversions all over your code.

Creating a `Temperature` class would be a good solution. To avoid re-inventing the wheel, it may be worth evaluating whether there are any existing scientific libraries which suit your problem.

When writing your own class, it would be a good idea to ensure that the internal representation of your class is always represented using the Base SI unit (i.e. Kelvin for temperature) and then ensure that other derived units such as Celsius/Fahrenheit are always calculated from that base unit.

If your `Temperature` class has to handle storing different internal representations of the same metric, you will likely end up with unnecessary complexity - for example, calculating the sum of `10C + 50F` is much easier when both are already internally represented by your class in Kelvin.

Also consider that code like this should ideally follow the Principle of Least Astonishment. So keep careful consideration about how you construct your objects so you can minimise ambiguity - e.g.

``````Temperature myTemp = new Temperature(50.0); // Wait! What unit is that 50.0?!?
``````

Obviously one of the reasons for writing a class such as `Temperature` is that numeric values are ambiguous. You might consider hiding any constructor which accepts `double` values and instead exposing public static "factory" methods which make your intentions clear.

``````Temperature myTemp = Temperature.fromFahrenheit(50.0);  // OK, that means 50F.
``````

Possible implementation of the `from` methods:

``````public class Temperature {

private double kelvin;

private Temperature(double k) {  // Private to prevent misuse
kelvin = k;
}

public static Temperature fromCelsius(double celsius) {
return new Temperature(celsius + 273.15);
}

public static Temperature fromFahrenheit(double fahrenheit) {
double temp = (fahrenheit - 32) / 1.8;
return fromCelsius(temp);
}
}
``````
• What would these From methods look like? – AJJ Mar 26 '16 at 15:43
• @ArukaJ updated with a possible example. – Ben Cottrell Mar 26 '16 at 15:56
• Hey, where's the `fromKelvin()` method? – candied_orange Mar 26 '16 at 16:03
• And why are you using PascalCase for methods instead of camelCase? – candied_orange Mar 26 '16 at 16:11
• @CandiedOrange Fair point, since it's a Java question. I guess I spend most of my time in C# so i usually default to PascalCase. Also, `fromKelvin()` could be an exercise for the reader :-) – Ben Cottrell Mar 26 '16 at 16:34

Actually its recommended to do so - create a class where you store your temp data, the class should take input and recognize it as C F K etc and then proceed to convert each one to the desired user temperature.

I would go for string recognition but if you are doing GUI things it can be different.

• How would it recognize the input as C F K? I can feed it as C F K, output it as C F K, and store it at C F K – AJJ Mar 26 '16 at 15:20
• Many ways as I said. Do you have any code so far so I can look and give you exact answer ? If not I can't tell you much but you can use either if statements or switch cases. – Ivan Uch Mar 26 '16 at 15:22
• I have a weight class that handles lbs vs kgs so maybe that is easier to do for now, I'll add some code – AJJ Mar 26 '16 at 15:23
• If you have that class (weight) just copy/paste it and refactor it so you can use it as temp class, it should be the same. – Ivan Uch Mar 26 '16 at 15:24
• Added code to OP – AJJ Mar 26 '16 at 15:24