Вопрос: почему хороший код должен избегать «магических чисел»? Ответ: потому что они превращают даже самый логичный алгоритм в загадку без подсказок. Ниже ― всё, что нужно знать о таких «магических» литералах и как сделать код более читаемым.
Что такое магические числа?
Магическое число — это любая числовая литерала (или строка), используемая в коде напрямую без объяснения смысла. Примеры:
if (age > 18) ...— число 18 здесь кажется понятным, но что если правило изменится?for(i = 0; i < 50; i++) ...— а что значит 50?total *= 1;18;, 1.18 точно налог НДС?
Никто, кроме автора, не узнает значения без комментария или именованной константы.
Зачем избегать магические чисел
- Повышение читаемости. Имя константы объясняет смысл.
- Упрощение сопровождения. Значение меняется в одном месте, а не в десятке.
- Меньше ошибок при копировании. «42» легко напечатать дважды и ошибиться.
- Самодокументированный код. Новый программист быстрее поймёт логику.
Как обезвредить магическое число
Именованные константы
// ❌ Плохо
if(score > 60) pass;
// ✅ Хорошо
const int MIN_PASS_SCORE = 60;
if(score > MIN_PASS_SCORE) pass;
Конфигурационные файлы или переменные окружения
- JSON, .env, INI-файлы для поргов, URL и т.д.
- Удобно передавать только значения без пересборки проекта.
Enum (перечисления)
enum Color { RED = 0xff0000, GREEN = 0x00ff00, BLUE = 0x0000ff };
Магические ID и интерфейсы
UUID, GUID тоже магичны без имени. Используйте:
const UUID INVENTORY_SERVICE_ID = "550e8400-e29b-41d4-a716-446655440000"
Распространённые магические зоны
| Сфера | Частые «магики» | Решение |
|---|---|---|
| Веб-сессии | 2592000 (30 дней в секундах) | SECONDS_IN_DAY * 30 |
| Финансы | 1.21 или 0.83 | NDS_RATE, DISCOUNT_FACTOR |
| Экраны | 800, 600 | MIN_SCREEN_WIDTH |
Мини-чек-лист по избавлению от магики
- ❓ Посмотрите на каждое число/строку и задайте вопрос: «Понятно ли без контекста?»
- 🔍 Используйте поиск по проекту: найдёт ли кто ошибку при вашем изменении?
- 🧪 Запустите статический анализатор (SonarQube, eslint, PMD).
- 💬 Коммит:
refactor: replace magic number 3600 with SEC_PER_HOUR
Бонус: памятка по именованию
DO:
const int HTTP_OK = 200;
const auto MAX_RETRY = 5;
DON’T:
int abc = 42;
Все вышеописанные принципы работают одинаково хорошо для C, C++, Java, Python, JavaScript, C# и других языков. Запомните: убрав магическое, вы дарите себе и коллегам спокойный ночной сон.