Насколько приемлемы ли жестко кодирующие литералы?

База кода, в которой я сейчас работаю, засорена жестко закодированными значениями.

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

Вот два примера, о которых я могу думать, что заставляет меня задаться вопросом, что лучше всего:

1. MyTextBox.Text = someCondition ? "Yes" : "No"
2. double myPercentage = myValue / 100;

В первом случае лучше всего создать класс, который позволяет мне делать MyHelper.Yes и MyHelper. Нет или что-то подобное в файле конфигурации (хотя это вряд ли изменится и кто знает если когда-нибудь может быть случай, когда его использование будет чувствительным к регистру).

Во втором случае поиск процента путем деления на 100 вряд ли когда-либо изменится, если законы математики не изменятся... но мне все еще интересно, есть ли лучший способ.

Может ли кто-нибудь предложить подходящий способ справиться с этим типом жесткого кодирования? И может ли кто-нибудь подумать о любых местах, где жесткое кодирование является приемлемой практикой?

Ответы

Ответ 1

И может ли кто-нибудь подумать о любых местах, где жесткое кодирование является приемлемой практикой?

  • Маленькие приложения
  • Проекты с одним человеком
  • Бросьте трассы
  • Краткосрочные проекты

Для коротких действий, которые не будут поддерживаться другими.

Gee Я только что понял, насколько в прошлом мне помогал кодер-хранитель:)

Ответ 2

Реальный вопрос заключается не в жестком кодировании, а скорее в повторении. Если вы возьмете отличный совет, найденный в "Прагматический программист" , просто не повторяйте себя (DRY).

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

Ответ 3

Конечно, жесткое кодирование иногда приемлемо. Следующая догма редко бывает полезной для практики, как использование вашего мозга.

(Пример этого, возможно, интересно вернуться к войнам goto. Сколько программистов вы знаете, которые будут ругаться всеми святыми, что goto является злым? Почему тогда Стив Макконнелл посвящает дюжину страниц измеренное обсуждение предмета в Code Complete?)

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

Чтобы не сказать, что "простейшая вещь" не должна быть читаемым кодом. Это может иметь смысл, даже в случае выброса, чтобы написать:

const MAX_CACHE_RECORDS = 50
foo = GetNewCache(MAX_CACHE_RECORDS)

Это независимо от того, что в течение трех итераций время может потребоваться настроить количество записей кэша, и вы можете закончить рефакторинг постоянной.

Просто помните, если вы переходите к экстремальным вещам вроде

const ONE_HUNDRED = 100
const ONE_HUNDRED_AND_ONE = 101

мы все приедем в The Daily WTF и посмеемся над вами.: -)

Think! Это все.

Ответ 4

Это никогда не бывает хорошо, и вы просто доказали это...

double myPercentage = myValue / 100;

Это НЕ процент. Что вы хотели написать:

double myPercentage = (myValue / 100) * 100;

Или вернее:

double myPercentage = (myValue / myMaxValue) * 100;

Но этот жестко закодированный 100 перепутался с вашим умом... Итак, перейдите к методу getPercentage, предложенному Коленом:)

double getpercentage(double myValue, double maxValue)
{
   return (myValue / maxValue) * 100;
}

Также, как предположил ctacke, в первом случае вы окажетесь в мире боли, если вам когда-нибудь понадобится локализовать эти литералы. Никогда не слишком сложно добавить еще пару переменных и/или функций.

Ответ 5

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

Ответ 6

Случай 1:. Когда вам нужно писать жесткий код: когда у вас нет причин думать, что он когда-либо изменится. Тем не менее, вы должны НИКОГДА работать с жестким кодом в строке. Найдите время, чтобы сделать статические переменные или глобальные переменные или независимо от того, что дает вам ваш язык. Сделайте их в классе, о котором идет речь, и если вы заметили, что два класса или области вашего кода имеют одно и то же значение ДЛЯ ОДИНАКОВЫХ ПРИЧИН (что означает не просто совпадение), укажите их на одно и то же место.

Случай 2:. В случае с корпусом 2 вы правы: законы "процент" не будут меняться (это разумно, здесь), поэтому вы можете жестко встраивать код.

Случай 3: Третий случай - это то, где вы думаете, что вещь может измениться, но вы не хотите/не успеваете загружать ResourceBundles или XML или что-то еще. В этом случае вы используете любой централизованный механизм, который вы можете - ненавидящий класс Singleton - хороший, и продолжайте с этим, пока вам не понадобится решать проблему.

Третий случай сложный: чрезвычайно сложно интернационализировать приложение, не выполняя его действительно... поэтому вам захочется записать жесткий код и просто надеяться, что когда ребята i18n начнут стучать, ваш код не будет код наихудшей дегустации:)

Изменить: Позвольте мне упомянуть, что я только что закончил проект рефакторинга, в котором предыдущий разработчик разместил строки подключения MySql в более чем 100 местах в коде (PHP). Иногда они были прописными, иногда они были в нижнем регистре и т.д., Поэтому их было трудно найти и заменить (хотя Netbeans и PDT действительно помогли). Есть причины, по которым он это сделал (проект, называемый POG, в основном заставляет эту глупость), но нет ничего, что кажется меньше, чем хороший код, чем повторение одной и той же вещи в миллионах мест.

Ответ 7

Лучший способ для вашего второго примера - определить встроенную функцию:

double getpercentage(double myValue)
{
   return(myValue / 100);
}

...

double myPercentage = getpercentage(myValue);

Таким образом, намного более очевидно, что вы делаете.

Ответ 8

Я не думаю, что ваш второй пример - пример жесткого кодирования. Это похоже на метод Halve(), который принимает значение, которое нужно использовать для разделения; не имеет смысла.

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

Следует избегать жесткого кодирования, так как Дракула избегает солнца. В конце концов, он снова укусит тебя в задницу.

Ответ 9

Текст условий должен быть в файле ресурсов; что он там для.

Ответ 10

нет.

То, что сейчас представляет собой приложение для простого выброса, завтра будет управлять вашим предприятием. Всегда используйте лучшие практики, или вы пожалеете об этом.

Ответ 11

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

  • Если значение может когда-либо измениться, сколько работы это и как трудно найти? Ввод его в одном месте и со ссылкой на то место в другом месте не так много работы и, следовательно, способ играть в нее безопасно.
  • Помогают ли программисты по программированию понять, почему это ценность? Если есть какие-либо сомнения, используйте именованную константу, которая объясняет смысл.

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

  • вы действительно хотите, чтобы клиенты меняли сами ценности.
  • Никакое значение, которое может быть помещено в файл конфигурации, может вызвать ошибку (переполнение буфера, кто-нибудь?)
  • ваш процесс сборки и развертывания отстой.

Ответ 12

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

Еще один способ взглянуть на это - как использовать хорошее соглашение об именах для констант, используемых на месте жестко закодированных литералов, дает дополнительные документация в программе.

Даже если номер используется только один раз, его все равно трудно распознать и даже может быть трудно найти для будущих изменений.

IMHO, упрощая чтение программ, должно быть второй характер для опытный профессионал программного обеспечения. Необработанные номера редко общаются осмысленно.

Дополнительное время, затраченное на использование константы с именованным ядром, приведет к читаемость кода (легко вспомнить) и полезно для будущего повторное использование (повторное использование кода).

Ответ 13

Я имею тенденцию рассматривать его с точки зрения объема и размера проекта.

Некоторые простые проекты, над которыми я являюсь сольным разработчиком? Конечно, я очень много программировал. Инструменты Я пишу, что только когда-нибудь буду использовать? Конечно, если он выполнит свою работу.

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

В вашем примере текстовое поле должно быть локализуемым, поэтому почему не класс, который обрабатывает это?

Ответ 14

Помните, что вы забудете значение любого неочевидного жестко заданного значения.

Поэтому будьте уверены, чтобы поместить короткий комментарий после каждого, чтобы напомнить вам.

Пример Delphi:

Длина: = Длина * 0.3048; {0.3048 преобразует ноги в метры}

Ответ 15

Все в порядке, пока вы не занимаетесь рефакторингом, модульным тестированием, отзывами на уровне пэра. И вы не хотите повторять клиентов. Кто заботится?

Ответ 16

Код всегда развивается. Когда вы изначально пишете материал, жесткое кодирование - это самый простой способ. Позже, когда придет необходимость изменить значение, его можно улучшить. В некоторых случаях эта потребность никогда не приходит.

Потребность может прийти во многих формах:

  • Значение используется во многих местах, и его необходимо изменить программистом. В этом случае явно необходима константа.

  • Пользователь должен иметь возможность изменять значение.

Я не вижу необходимости избегать жесткого кодирования. Я вижу необходимость изменить ситуацию, когда есть явная необходимость.

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

Ответ 17

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

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

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

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

Ответ 18

Для первого значения это действительно зависит. Если вы не ожидаете какого-либо широкого применения вашего приложения, и интернационализация никогда не будет проблемой, я думаю, что это в основном нормально. Однако, если вы пишете какое-то программное обеспечение с открытым исходным кодом или что-то с более широкой аудиторией, подумайте о том, что в один прекрасный день его нужно перевести. В этом случае вам может быть лучше использовать строковые ресурсы.

Ответ 19

У меня когда-то был босс, который отказывался ничего не делать, потому что, по его мнению, он дал ему полный контроль над программным обеспечением и предметами, связанными с программным обеспечением. Проблема заключалась в том, что, когда аппаратное обеспечение сработало, запущенное программное обеспечение, сервер получил переименование... то есть он должен был найти свой код. Это заняло некоторое время. Я просто нашел шестнадцатеричный редактор и взломал его, а не ожидал.

Ответ 20

Жесткое кодирование должно быть запрещено навсегда. Хотя в вас очень простые примеры, я не вижу ничего плохого в использовании их в любом проекте.

На мой взгляд, жесткое кодирование - это когда вы считаете, что переменная/значение/определение и т.д. никогда не изменится и не создаст весь ваш код на основе этого убеждения.

Пример такого жесткого кодирования - книга Teach Yourself C в 24 часа, которую следует избегать.

Ответ 21

Я обычно добавляю набор вспомогательных методов для строк и чисел.

Например, когда у меня есть строки, такие как "да" и "нет", у меня есть функция с именем __, поэтому я вызываю __ ( "да" ); который начинается в проекте, просто вернув первый параметр, но когда мне нужно сделать более сложные вещи (например, internationaizaton), он уже существует, и param может быть использован ключ.

Другим примером является НДС (форма налога на прибыль в Великобритании) в интернет-магазинах, в последнее время он изменился с 17,5% до 15%. Любой, кто жестко закодировал НДС, делая:

$vat = $price * 0.175;

должен был пройти все ссылки и изменить его на 0,15, вместо этого супер полезным способом было бы иметь функцию или переменную для НДС.

По-моему, все, что может измениться, должно быть записано изменчивым образом. Если я сделаю то же самое более 5 раз в тот же день, тогда он станет функцией или config var.