- Shift Elevate
- Posts
- Magic Numbers: Replace Magic Number with Named Constant | Clean Code
Magic Numbers: Replace Magic Number with Named Constant | Clean Code
Magic Numbers are literal values scattered throughout code that lack clear meaning.
We will see how we can refactor them using named constants for better readability and maintainability.
Clean Code Reference
⚠️ Code Smell: Magic Numbers
✅ Refactoring: Replace Magic Number with Named Constant
🎯 Goal: Self-documenting code with clear intent
The Magic Numbers code smell occurs when literal numbers, strings, or other values appear in code without clear meaning or context. The Replace Magic Number with Named Constant refactoring technique replaces these literals with descriptive constants that make the code self-documenting.
The Code Smell: Magic Numbers
Magic Numbers are one of the most common code smells that reduce code readability and maintainability. When literal values appear in code without clear context, they make the code harder to understand and modify. These numbers often represent business rules, configuration values, or mathematical constants that should be clearly documented.
Symptoms | Impact |
---|---|
Literal numbers without clear meaning | Reduced readability |
Repeated magic numbers throughout code | Difficult to maintain |
Business rules hidden in literals | Higher bug risk |
Here's a typical example of Magic Numbers:
public class OrderProcessor {
public double calculateDiscount(Order order) {
double total = order.getTotal();
// Magic Numbers: What do these values mean?
if (order.getCustomer().isPremium()) {
total = total * 0.9; // What is 0.9?
}
if (total > 100.0) {
total = total * 0.95; // What is 100.0 and 0.95?
}
return total;
}
public boolean isEligibleForFreeShipping(Order order) {
// Magic Numbers: What do these values represent?
return order.getTotal() >= 50.0 && order.getWeight() <= 10.0;
}
public int calculateDeliveryDays(String shippingMethod) {
switch (shippingMethod) {
case "STANDARD":
return 5; // What does 5 mean?
case "EXPRESS":
return 2; // What does 2 mean?
case "OVERNIGHT":
return 1; // What does 1 mean?
default:
return 7; // What does 7 mean?
}
}
}
In this example, the magic numbers like 0.9, 100.0, 0.95, 50.0, 10.0, 5, 2, 1, and 7 have no clear meaning. They represent business rules and configuration values that should be clearly documented and easily modifiable.
The Refactoring: Replace Magic Number with Named Constant
The Replace Magic Number with Named Constant refactoring technique replaces literal values with descriptive constants that clearly communicate their purpose and meaning. This makes the code self-documenting and easier to maintain.
Step by Step Refactoring Process:
Identify magic numbers in the code that lack clear meaning.
Determine the purpose of each magic number (business rule, configuration, etc.).
Create descriptive constants with meaningful names.
Replace magic numbers with the named constants.
Group related constants in appropriate classes or enums.
Here's the refactored version:
public class OrderProcessor {
// Discount constants
private static final double PREMIUM_CUSTOMER_DISCOUNT_RATE = 0.9; // 10% discount
private static final double BULK_ORDER_DISCOUNT_RATE = 0.95; // 5% discount for orders over threshold
private static final double BULK_ORDER_AMOUNT_THRESHOLD = 100.0; // $100 minimum for bulk discount
// Shipping constants
private static final double FREE_SHIPPING_THRESHOLD = 50.0; // $50 minimum
private static final double MAX_FREE_SHIPPING_WEIGHT = 10.0; // 10 lbs maximum
// Delivery time constants (in days)
private static final int STANDARD_DELIVERY_DAYS = 5;
private static final int EXPRESS_DELIVERY_DAYS = 2;
private static final int OVERNIGHT_DELIVERY_DAYS = 1;
private static final int DEFAULT_DELIVERY_DAYS = 7;
public double calculateDiscount(Order order) {
double total = order.getTotal();
if (order.getCustomer().isPremium()) {
total = total * PREMIUM_CUSTOMER_DISCOUNT_RATE;
}
if (total > BULK_ORDER_AMOUNT_THRESHOLD) {
total = total * BULK_ORDER_DISCOUNT_RATE;
}
return total;
}
public boolean isEligibleForFreeShipping(Order order) {
return order.getTotal() >= FREE_SHIPPING_THRESHOLD &&
order.getWeight() <= MAX_FREE_SHIPPING_WEIGHT;
}
public int calculateDeliveryDays(String shippingMethod) {
switch (shippingMethod) {
case "STANDARD":
return STANDARD_DELIVERY_DAYS;
case "EXPRESS":
return EXPRESS_DELIVERY_DAYS;
case "OVERNIGHT":
return OVERNIGHT_DELIVERY_DAYS;
default:
return DEFAULT_DELIVERY_DAYS;
}
}
}
Benefits of Replace Magic Number with Named Constant
Benefit | Description |
---|---|
Improved Readability | Constants with descriptive names make the code self documenting, clearly communicating the purpose and meaning of each value. |
Enhanced Maintainability | Business rules and configuration values are centralized and easily modifiable without searching through the entire codebase. |
Reduced Bug Risk | Clear constant names reduce the likelihood of using incorrect values and make it easier to spot errors during code review. |
When to Apply Replace Magic Number with Named Constant Refactoring
Literal numbers, strings, or other values that lack clear meaning.
Repeated magic numbers throughout the codebase.
Business rules or configuration values embedded in code.
Mathematical constants or thresholds that should be clearly documented.
Apply Replace Magic Number with Named Constant refactoring to one set of magic numbers in your current project today. Start with the magic numbers that represent the most important business rules.
Repository & Resources
Complete Code Examples: Clean Code Repository
Find the complete implementation of Magic Numbers refactoring and other clean code techniques in our dedicated repository. Each example includes:
Before and after code comparisons
Unit tests demonstrating the improvements
Found this helpful? Share it with a colleague who's struggling with Magic Numbers. Have questions about refactoring constants in your codebase? Email us directly, we read every message and the best questions become future newsletter topics.