Replace Magic Number with Symbolic Constant
Problem
Your code uses a number that has a certain meaning to it.
potentialEnergy(mass: number, height: number): number {
return mass * height * 9.81;
}
Solution
Replace this number with a constant that has a human-readable name explaining the meaning of the number.
static const GRAVITATIONAL_CONSTANT = 9.81;
potentialEnergy(mass: number, height: number): number {
return mass * height * GRAVITATIONAL_CONSTANT;
}
Why Refactor
A magic number is a numeric value that’s encountered in the source but has no obvious meaning. This “anti-pattern” makes it harder to understand the program and refactor the code.
Yet more difficulties arise when you need to change this magic number. Find and replace won’t work for this: the same number may be used for different purposes in different places, meaning that you will have to verify every line of code that uses this number.
Benefits
-
The symbolic constant can serve as live documentation of the meaning of its value.
-
It’s much easier to change the value of a constant than to search for this number throughout the entire codebase, without the risk of accidentally changing the same number used elsewhere for a different purpose.
-
Reduce duplicate use of a number or string in the code. This is especially important when the value is complicated and long (such as
3.14159
or0xCAFEBABE
).
Good to Know
Not all numbers are magical
If the purpose of a number is obvious, there’s no need to replace it. A classic example is:
for (i = 0; i < сount; i++) { ... }
Alternatives
-
Sometimes a magic number can be replaced with method calls. For example, if you have a magic number that signifies the number of elements in a collection, you don’t need to use it for checking the last element of the collection. Instead, use the standard method for getting the collection length.
-
Magic numbers are sometimes used as type code. Say that you have two types of users and you use a number field in a class to specify which is which: administrators are
1
and ordinary users are2
.In this case, you should use one of the refactoring methods to avoid type code:
How to Refactor
-
Declare a constant and assign the value of the magic number to it.
-
Find all mentions of the magic number.
-
For each of the numbers that you find, double-check that the magic number in this particular case corresponds to the purpose of the constant. If yes, replace the number with your constant. This is an important step, since the same number can mean absolutely different things (and replaced with different constants, as the case may be).