Допустим ли хардкод из предметной области?
Столкнулся с тем, что иногда приходится в проектах хардкодить "магические числа" из предметной области. Не знаю как с ними быть. Самый очевидный пример - часы в минуты
float minutes2hours(float hours){
return hours*60;
}
Для нас с вами понятно, что 60 минут в часе это то, что не скоро изменится и название функции говорит о том, что можно оставить это в таком виде,и это поймёт любой читающий.
Однако, есть вещи, которые столь же очевидны, но только тем, кто знает предметную область. Скажем смена шахтёра не может превышать 6 часов законодательно и тогда метод, который за этим следит будет таким :
bool isWorkerShiftContinue(float timeOfWork){
return (bool)(timeOfWork <= 6*60);
}
И что это за 6*60 ?! Я чувствую себя не комфортно, оставляя это так.
Я могу это вынести в переменную, но тогда их не напасёшься и в коде снова чёрт ногу сломит. Особенно в методах, которые высчитывают что-то сложное. Более того, возникает вопрос, а что если через полгода им сократят время работы до 5 часов??
Помогите, где та мера, когда можно хардкодить данные, которые относятся к предметной облсти?
ЗЫ c++
Ответы (2 шт):
Нужно использовать именованые константы. И, если одного имени кажется недостаточно для фиксации смысла, дополнять их комментарием.
(пример псевдокодом - я не уверен, на каком языке примеры из вашего вопроса, и как правильно в нём задавать константы и комментарии)
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);
}
Независимо от предметной области, лучше никогда не хардкодить "магические константы" прямо в том месте, где они используются.
Что используется только в данном файле/классе - просто выносится в начало кода, там, где лежат константы, и там прописывается именованной константой.
Что используется в нескольких файлах - выносится опять же в виде констант в отдельный файл, который можно подключить во всех файлы кода, где это будет использоваться.
Что должно иногда меняться пользователями, так, чтобы можно было поменять это без перекомпиляции программы - можно вынести в конфиг-файл.
Что должно меняться как-то централизовано в локальной сети, или скажем что может представлять из себя несколько наборов конфигураций, которые могут переключаться в зависимости от каких-то условий - можно вынести в БД.
Повторюсь: предметная область или нет - это не важно, "магические константы", конфигурации и всё прочее должны рассматриваться единообразно, с точки зрения наилучшей архитектуры кода.