Что такое магические числа в программировании

Узнайте, почему программисты называют некоторые константы магические числа, как они влияют на код и какие практики помогут заменить их на понятные значения.

Вопрос: почему хороший код должен избегать «магических чисел»? Ответ: потому что они превращают даже самый логичный алгоритм в загадку без подсказок. Ниже ― всё, что нужно знать о таких «магических» литералах и как сделать код более читаемым.

Что такое магические числа?

Магическое число — это любая числовая литерала (или строка), используемая в коде напрямую без объяснения смысла. Примеры:

  • if (age > 18) ... — число 18 здесь кажется понятным, но что если правило изменится?
  • for(i = 0; i < 50; i++) ... — а что значит 50?
  • total *= 1;18;, 1.18 точно налог НДС?

Никто, кроме автора, не узнает значения без комментария или именованной константы.

Зачем избегать магические чисел

  1. Повышение читаемости. Имя константы объясняет смысл.
  2. Упрощение сопровождения. Значение меняется в одном месте, а не в десятке.
  3. Меньше ошибок при копировании. «42» легко напечатать дважды и ошибиться.
  4. Самодокументированный код. Новый программист быстрее поймёт логику.

Как обезвредить магическое число

Именованные константы

// ❌ Плохо
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# и других языков. Запомните: убрав магическое, вы дарите себе и коллегам спокойный ночной сон.