Refactoring: Magic Numbers

هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

Another type of refactoring patterns is the Magic Number pattern.

Magic numbers are numbers with special meaning and value that usually are not obvious, such as PI. They are really nasty when you need to reference the same number many times. If the number might ever change, making the change is a nightmare. Even if you don’t make a change, you have the difficulty of figuring out what is going on.

If you have a magic number into your code and you use it frequently, you can create a constant, name it after the meaning, and replace the number with it. Most languages support constants. There is no cost in performance and there is a great improvement in readability.

But, before you do this refactoring, you should always look for an alternative. Look at how the magic number is used. Often you can find a better way to use it. If the magic number is a type code, consider replace type code with a class. If the magic number is the length of an array, use anArray.length instead when you are looping through the array. Otherwise, you can go and create your constant.

For example, the following code converts between meters and feet, and it uses a magic number that’s the feet in one meter:

// C# Code

public static double ConvertMetersToFeet(double meters)
{
    return meters * 3.2808398950131233595800524934383;
}
public static double ConvertFeetToMeters(double feet)
{
    return feet / 3.2808398950131233595800524934383;
}
' VB.NET Code

Public Function ConvertMetersToFeet(meters As Double) As Double
    Return meters * 3.2808398950131233595800524934383
End Function

Public Function ConvertFeetToMeters(feet As Double) As Double
    Return feet / 3.2808398950131233595800524934383
End Function

So, we can refactor the code to be:

// C# Code

public const double MeterFeet = 3.2808398950131233595800524934383;

public static double ConvertMetersToFeet(double meters)
{
    return meters * MeterFeet;
}
public static double ConvertFeetToMeters(double feet)
{
    return feet / MeterFeet;
}
' VB.NET Code

Public Const MeterFeet As Double _
    = 3.2808398950131233595800524934383

Public Function ConvertMetersToFeet(meters As Double) As Double
    return meters * MeterFeet
End Function

Public Function ConvertFeetToMeters(feet As Double) As Double
    return feet / MeterFeet
End Function

The lesson quoted from the book “Refactoring: Improving the Design of Existing Code” by Martin Fowler. Code snippets by Just Like a Magic.