Magic Numbers and Strings

Magic Numbers and Strings

Have you ever stumbled upon a number or string in your code and thought, 'What on earth does that mean?' If so, you’ve likely encountered a magic value—a hidden culprit that makes code harder to read and maintain. In this installment of our Code Smell series, we will explore Magic Numbers and Strings, why they are problematic, and how to eliminate them.
Let’s start by taking a look at these two code samples:

Example A

public double calculateDiscount(double price) {
    return price * 0.15;   // What is 0.15? A mystery!
}

Example B

private static final double DISCOUNT_RATE = 0.15;

public double calculateDiscount(double price) {
    return price * DISCOUNT_RATE;
}

Which of the above examples is easier to understand?

Clearly, Example B is easier to understand. Here’s why: the line private static final double DISCOUNT_RATE = 0.15; provides the reader with immediate context, explaining that 0.15 represents the discount rate. In Example A, the value 0.15 is 'magic'—its purpose is entirely unclear, leaving the reader to guess or search for its meaning.

What are Magic Numbers and Strings?

Magic Numbers and Strings are mysterious numbers, strings, or other values used in code without clear explanation. As seen in the first code sample, the magic number 0.15 lacks context. Now, imagine that 0.15 value is used in multiple places across the codebase. If you need to update the discount rate, you will have to manually change it everywhere, which could quickly become a tedious and error-prone task.

These magic values make it difficult for anyone, including your future self, to understand what’s going on in your codebase. It is important to note that magic values are not limited to just numbers and strings; they can also be booleans, dates, and other types of data.

Why are Magic Numbers and Strings considered bad?

1. They make code harder to understand at a glance, making it difficult for developers to grasp the code logic quickly.

2. They make code difficult to maintain. If the magic value needs to be changed, you will have to hunt down every instance in the code where it was used.

3. They are error-prone, especially when you have the magic value in multiple parts of your code. You may have typos when updating these values.

How can you avoid Magic Numbers and Strings?

The best way to avoid magic values is to use meaningful names for variables and constants. Descriptive constants provide context and indicate the purpose of a value, making your code easier to read and maintain. If multiple related constants exist, consider grouping them in an enum for better organization.

Below is an example of using a meaningful constant to avoid a magic string:

private static final String EMAIL_REGEX = "^[A-Za-z0-9+_.-]+@(.+)$";

boolean isValid = email.matches(EMAIL_REGEX);

Conclusion

Magic values, though often overlooked, can be a significant source of bugs and maintenance headaches. They introduce unnecessary complexity, but fortunately, they are easily avoidable. By making simple changes, such as using constants, enums, and other best practices, we can write cleaner and more maintainable code while reducing the risk of subtle bugs.

So, the next time you are tempted to hardcode a value, ask yourself:

"Will my future self or anyone who reads this code understand this value at a glance?"

If not, it's time to refactor! 🔄✨