Jump to content

Recommended Posts

I have an application that does its computations using English Imperial (EI) units.  It uses a procedural function to convert from EI to SI units, whenever they are needed.

 

As I am refactoring code, I am looking for better ways to handle this.  Assume that I get my values from something like this: $myObject->getValue();

  1. $myObject->getSIValue(); //have the object itself do the conversion.  I think it's bad, as my object should not "know" of conversion.  Plus, I'd have to duplicate conversion code in different objects
  2. $conversionObject->convertLengthFromEnglishToMetric($myObject->getValue());  //perhaps better, but it looks convoluted.
  3. convertLengthEnglishToMetric($myObject->getValue());  //keep procedural function as a "library"

Also, since I usually only convert from English to Metric and not the other way around, I can probably just do a ConverterObject that by default accepts EI and returns SI.  What would you do?

Wouldn't it be easier to just make all the conversions work with the same units everywhere?

 

I'm inclined to just hardcoding the multiplication/division operation when needed. The numbers aren't going to change anytime soon, and if any of the underlying code changes units you still have to spelunk into your code to change the conversion logic. But if you really want a more complicated solution then it depends how complicated you want to get: #3 is simple while #2 is more flexible. I suggest you don't go too far because all it seems you need to do is convert a handful of units from SI to Imperial in a few places, and while an OOP solution is cool and all, you're adding a lot more overhead and complexity without gaining much in return.

 

The more flexible-type solutions vary based on needs. One easy way to describe is to maintain a mapping of factors (or maybe functions in case of conversions like Fahrenheit/Celsius) and call a function using the labels.

array(
	"length" => array(
		// picking m as the base unit
		"ft" => 0.3048,
		"m" => 1
	)
)
convert("length", "ft", "m", $myObject->getValue()); // value * 0.3048 / 1
convert("length", "m", "ft", $myObject->getValue()); // value * 1 / 0.3048
You can OOP that by

a) Passing "length" to a constructor and converting any unit to any other unit, or

b) Passing all three arguments and converting a value "to" or "from" (which sounds closer to your needs)

I prefer having a single point of failure, so that means not doing mult/div operations everywhere in the code.  That will amount to code duplication and occasional errors/omissions perhaps.

This is why I want some kind of a function or method and not worry about operator ordering.

 

I like your approach with arrays.  But not certain I get it.   How do you use this array?  Oh wait, I guess like this:

function convert($value, $baseUnit, $from, $to)
{
    $units=array(...);
    return $value * $units[$baseUnit][$from] / arrayContainer[$baseUnit][$to];
}

Edited by dennis-fedco
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.