Мы все знаем, что магические числа (жестко запрограммированные значения) могут нанести ущерб вашей программе, особенно когда пришло время изменить часть кода, в которой нет комментариев, но где вы проводите черту?
Например, если у вас есть функция, которая рассчитывает количество секунд между двумя днями, заменить
seconds = num_days * 24 * 60 * 60
с
seconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE
В какой момент вы решаете, что совершенно очевидно, что означает жестко закодированное значение, и оставляете его в покое?
refactoring
coding-standards
maintainability
oosterwal
источник
источник
seconds = CALC_SECONDS(num_days);
TimeSpan.FromDays(numDays).Seconds;
HOURS_PER_DAY will never need to be altered
) вы никогда не будете кодировать программное обеспечение, развернутое на Марсе. : PОтветы:
Есть две причины использовать символические константы вместо числовых литералов:
Для упрощения обслуживания, если магические числа меняются. Это не относится к вашему примеру. Крайне маловероятно, что число секунд в часе или количество часов в дне изменится.
Для улучшения читаемости. Выражение «24 * 60 * 60» довольно очевидно почти для всех. «SECONDS_PER_DAY» тоже, но если вы ищете ошибку, вам, возможно, придется проверить, что SECONDS_PER_DAY был определен правильно. В краткости есть ценность.
Для магических чисел, которые появляются ровно один раз и не зависят от остальной части программы, решение о создании символа для этого числа является делом вкуса. Если есть сомнения, создайте символ.
Не делайте этого:
источник
publid final int FOUR = 3;
public static int THREE = 3;
... примечание - нетfinal
!Я бы придерживался правила никогда не иметь магических чисел.
В то время как
Прекрасно читается большую часть времени после того, как кодировался по 10 часов в день в течение трех или четырех недель в режиме хруста
намного легче читать.
Предложение FrustratedWithFormsDesigner лучше:
или даже лучше
Вещи перестают быть очевидными, когда ты очень устал. Код в обороне .
источник
Время сказать нет почти всегда. Временами, когда я нахожу, что проще просто использовать жестко запрограммированные числа в таких местах, как макет пользовательского интерфейса - создание константы для позиционирования каждого элемента управления в форме становится очень трудоемким и утомительным, и если этот код обычно обрабатывается дизайнером пользовательского интерфейса, это не имеет большого значения. ... если пользовательский интерфейс не выложен динамически, не использует относительные позиции для некоторой привязки или написан от руки. В этом случае я бы сказал, что лучше определить некоторые значимые константы для макета. И если вам нужен фактор выдумки здесь или там, чтобы выровнять / расположить что-то «как раз правильно», это также должно быть определено.
Но в вашем примере я думаю, что лучше заменить
24 * 60 * 60
наDAYS_TO_SECONDS_FACTOR
.Я допускаю, что жестко запрограммированные значения также хороши, когда контекст и использование полностью понятны. Это, однако, является призывом к суждению ...
Пример:
Как указывал @rmx, использование 0 или 1 для проверки, является ли список пустым или, возможно, в границах цикла, является примером случая, когда цель константы очень ясна.
источник
0
или1
я считаю.if(someList.Count != 0) ...
лучше чемif(someList.Count != MinListCount) ...
. Не всегда, но в целом.Остановитесь, когда вы не можете закрепить значение или цель числа.
намного легче читать, чем просто используя цифры. (Хотя это можно сделать более читабельным, если иметь одну
SECONDS_PER_DAY
константу, но это совершенно отдельный вопрос.)Предположим, что разработчик, глядя на код, может видеть, что он делает. Но не думайте, что они тоже знают почему. Если ваш постоянный помогает понять почему, пойти на это. Если нет, не надо.
Если у вас будет слишком много констант, как было предложено в одном ответе, рассмотрите возможность использования внешнего файла конфигурации вместо этого, поскольку наличие десятков констант в файле не совсем улучшает читаемость.
источник
Я бы, вероятно, сказал «нет» на такие вещи, как:
И определенно сказал бы «нет»:
источник
Один из лучших примеров, которые я нашел для продвижения использования констант для очевидных вещей, таких как
HOURS_PER_DAY
:Мы подсчитывали, как долго вещи сидят в очереди на работу. Требования были слабо определены, и программист жестко запрограммирован
24
во многих местах. В конце концов мы поняли, что было бы несправедливо наказывать пользователей за то, что они сидели за проблемой в течение 24 часов, тогда как на самом деле они работают только по 8 часов в день. Когда задача пришла, чтобы исправить это И посмотреть, какие другие проблемы могут возникать в других отчетах, было довольно трудно выполнить поиск / поиск по коду для 24, было бы намного проще выполнить поиск / поиск по запросу.HOURS_PER_DAY
источник
Я думаю, что до тех пор, пока число является полностью постоянным и не имеет возможности измениться, это вполне приемлемо. Так что в вашем случае
seconds = num_days * 24 * 60 * 60
это нормально (при условии, конечно, что вы не делаете глупостей, например, выполняете подобные вычисления внутри цикла) и, возможно, лучше для удобства чтения, чемseconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE
.Это когда ты делаешь такие вещи, это плохо
lineOffset += 24; // 24 lines to a page
Даже если вы не можете разместить больше строк на странице или даже если у вас нет намерений изменять ее, используйте вместо этого постоянную переменную, потому что однажды она снова станет преследовать вас. В конечном счете, смысл в удобочитаемости, а не в сохранении двух циклов вычислений на процессоре. Это больше не 1978, когда драгоценные байты были сжаты для всей их ценности.
источник
Это прекрасно. Это на самом деле не магические числа, поскольку они никогда не изменятся.
Любые числа, которые могут разумно измениться или не имеют очевидного значения, должны быть помещены в переменные Что означает почти все из них.
источник
seconds = num_days * 86400
еще будет приемлемым? Если бы подобное значение использовалось несколько раз в разных файлах, как бы вы убедились, что кто-то случайно не набралseconds = num_days * 84600
в одном или двух местах?Я бы не стал создавать константы (магические значения) для преобразования значения из одной единицы в другую. В случае конвертации я предпочитаю имя говорящего метода. В этом примере это будет, например,
DayToSeconds(num_days)
внутренний метод не нуждается в магических значениях, потому что значение «24» и «60» понятно.В этом случае я бы никогда не использовал секунды / минуты / часы. Я бы использовал только TimeSpan / DateTime.
источник
Используйте контекст в качестве параметра, чтобы решить
Например, у вас есть функция, которая называется «CalculateSecondsBetween: aDay and: anotherDay», вам не нужно много объяснять, что делают эти числа, потому что имя функции довольно представительное.
И еще один вопрос: какие есть возможности рассчитать его по-другому? Иногда есть много способов сделать то же самое, поэтому, чтобы помочь будущим программистам и показать им, какой метод вы использовали, определение констант может помочь понять это.
источник