Допустим ли хардкод из предметной области?

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

float minutes2hours(float hours){
    return hours*60;
}

Для нас с вами понятно, что 60 минут в часе это то, что не скоро изменится и название функции говорит о том, что можно оставить это в таком виде,и это поймёт любой читающий.

Однако, есть вещи, которые столь же очевидны, но только тем, кто знает предметную область. Скажем смена шахтёра не может превышать 6 часов законодательно и тогда метод, который за этим следит будет таким :

bool isWorkerShiftContinue(float timeOfWork){
    return (bool)(timeOfWork <= 6*60);
}

И что это за 6*60 ?! Я чувствую себя не комфортно, оставляя это так. Я могу это вынести в переменную, но тогда их не напасёшься и в коде снова чёрт ногу сломит. Особенно в методах, которые высчитывают что-то сложное. Более того, возникает вопрос, а что если через полгода им сократят время работы до 5 часов??
Помогите, где та мера, когда можно хардкодить данные, которые относятся к предметной облсти?

ЗЫ c++


Ответы (2 шт):

Автор решения: Xander

Нужно использовать именованые константы. И, если одного имени кажется недостаточно для фиксации смысла, дополнять их комментарием.

(пример псевдокодом - я не уверен, на каком языке примеры из вашего вопроса, и как правильно в нём задавать константы и комментарии)

const MINUTES_IN_HOUR = 60

// Максимальная продолжительность смены шахтёра согласно закону N...
const MINER_SHIFT_MAX_HOURS = 6

bool isWorkerShiftContinue(float timeOfWork){
    return (bool)(timeOfWork <= MINER_SHIFT_MAX_HOURS * MINUTES_IN_HOUR);
}
→ Ссылка
Автор решения: CrazyElf

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

  • Что используется только в данном файле/классе - просто выносится в начало кода, там, где лежат константы, и там прописывается именованной константой.

  • Что используется в нескольких файлах - выносится опять же в виде констант в отдельный файл, который можно подключить во всех файлы кода, где это будет использоваться.

  • Что должно иногда меняться пользователями, так, чтобы можно было поменять это без перекомпиляции программы - можно вынести в конфиг-файл.

  • Что должно меняться как-то централизовано в локальной сети, или скажем что может представлять из себя несколько наборов конфигураций, которые могут переключаться в зависимости от каких-то условий - можно вынести в БД.

Повторюсь: предметная область или нет - это не важно, "магические константы", конфигурации и всё прочее должны рассматриваться единообразно, с точки зрения наилучшей архитектуры кода.

→ Ссылка