Найти в Дзене
Tominoff

Как избавиться от магических чисел в коде — простой рефакторинг за 15 минут

В каждом проекте есть код с временными интервалами. Вот типичные примеры: const COOKIE_TTL = 2592000; // 30 дней в секундах? const CACHE_EXPIRE = 1800000; // 30 минут в миллисекундах? const API_TIMEOUT = 5000; // 5 секунд? Проблемы этого кода: Разные API и системы ожидают время в разных форматах, например - Куки → секунды, setTimeout → миллисекунды. Без явного указания единиц легко ошибиться Даже зная, что:
3600 = 1 час в секундах
86400 = 1 день в секундах
Приходится мысленно преобразовывать значения Особенно при:
• Составных интервалах (30 * 24 * 3600 * 1000)
• Изменении требований (например, переход с минут на секунды)
• Один пропущенный множитель — и таймеры работают неверно В JavaScript нет встроенного класса для работы с временными интервалами, но его легко добавить в проект. Вот как это меняет подход к работе со временем: Как это выглядит на практике: // Было const TIMEOUT = 3600 * 24 * 30; // 30 дней в секундах? const DELAY = 300000; // 5 минут в миллисекундах? // Ста
Оглавление
Творчество gigachat
Творчество gigachat

Проблема

В каждом проекте есть код с временными интервалами. Вот типичные примеры:

const COOKIE_TTL = 2592000; // 30 дней в секундах?
const CACHE_EXPIRE = 1800000; // 30 минут в миллисекундах?
const API_TIMEOUT = 5000; // 5 секунд?

Проблемы этого кода:

  • Неочевидные единицы измерения

Разные API и системы ожидают время в разных форматах, например - Куки → секунды, setTimeout → миллисекунды. Без явного указания единиц легко ошибиться

  • Когнитивная нагрузка

Даже зная, что:
3600 = 1 час в секундах
86400 = 1 день в секундах
Приходится мысленно преобразовывать значения

  • Ошибки в расчётах

Особенно при:
• Составных интервалах (30 * 24 * 3600 * 1000)
• Изменении требований (например, переход с минут на секунды)
• Один пропущенный множитель — и таймеры работают неверно

Решение - добавить простую абстракцию

В JavaScript нет встроенного класса для работы с временными интервалами, но его легко добавить в проект. Вот как это меняет подход к работе со временем:

  • Делает код самодокументируемым и интуитивно понятным
  • Автоматизирует преобразование единиц
  • Исключает ошибки в расчётах

Как это выглядит на практике:

// Было
const TIMEOUT = 3600 * 24 * 30; // 30 дней в секундах?
const DELAY = 300000; // 5 минут в миллисекундах?
// Стало
const TIMEOUT = TimeInterval.fromDays(30).toSeconds();
const DELAY = TimeInterval.fromMinutes(5).toMillis();

Реальные кейсы из нашего проекта

1. Конфигурация сервисов

Было:

// 12 часов в миллисекундах
const ATOL_TOKEN_EXPIRES = 43200000;

Стало:

const ATOL_TOKEN_EXPIRES = TimeInterval.fromHours(12).toMillis();

2. Работа с куками

Было:

// 180 дней в секундах
response.cookie('session', token, {
maxAge: 15552000
});

Стало:

response.cookie('session', token, {
maxAge: TimeInterval.fromDays(180).toSeconds()
});

Преимущества такого подхода

  • Самодокументируемость

fromHours(2).toMillis() явно читается лучше, чем 7200000 или 2 * 60 * 60 * 1000.
Не нужно добавлять поясняющие комментарии, сразу видно какие единицы измерения требует сервис

  • Безопасность

Невозможно перепутать секунды и миллисекунды

  • Гибкость

Изменяем единицы измерения в одном месте

Итог:

Да, можно запомнить, что 86400 — это сутки в секундах. Но зачем напрягать память, если код может быть понятным сразу? Простой класс вроде TimeInterval делает временные интервалы очевидными без лишних комментариев и вычислений.

После внедрения мы:

  • Перестали тратить время на расшифровку чисел
  • Уменьшили количество ошибок
  • Сделали код понятнее для новых разработчиков

Полную реализацию можно найти в GitHub Gist.