Почему использование значения корзины по умолчанию для строки неверно?

#java #c# #syntax #architecture

#java #c# #синтаксис #архитектура

Вопрос:

tl; dr;

Зачем использовать

 string myVariable = "someInitialValueDifferentThanUserValue99999999999";
 

поскольку значение по умолчанию неверно?

объяснение ситуации:

У меня была дискуссия с коллегой на моем рабочем месте.

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

 string myVariable = "someInitialValueDifferentThanUserValue99999999999";
...
if(myVariable == "someInitialValueDifferentThanUserValue99999999999")
{
   ...
}
 

Для меня совершенно очевидно и интуитивно понятно, что это неправильно.
Но я не мог привести хороший аргумент в пользу этого, помимо этого:

  • это непрофессионально.
  • существует небольшая вероятность того, что кто-то введет то же значение.

Однажды я прочитал, что если у вас такая ситуация, ваша архитектура или привычки программирования неверны.

редактировать: Спасибо за ответы. Я нашел решение, которое меня удовлетворило, поэтому я делюсь с другими:

Полезно создать значение защиты bool, которое указывает, была ли выполнена инициализация определенного объекта.

И на основе этой частной переменной bool я могу сделать вывод, если я играю со строкой, которая является пустым значением по умолчанию «» из моего механизма (то есть во время инициализации) или пустым значением от пользователя.

Для меня это более элегантный способ.

Комментарии:

1. Подробности: Ситуация более сложная, потому что мы используем SDK и некоторые встроенные фреймворки, и, наконец, у нас есть некоторое значение слота, которое работает в режиме (value, HasValue). Где значение является фактическим значением, а HasValue — логическое значение, которое указывает, есть ли у нас значение вообще. Что-то вроде ручного обнуления (возможно, у нас нет обнуляемых значений в framework). Тогда мы немного ограничены конструктором и устанавливаем методы значений для таких кортежей. Из-за этого мы не можем использовать null в качестве нашего неинициализированного значения по умолчанию и пустой строки в качестве пустого ввода пользователя.

2. Возможно ли использование Optional<String> ? Потому что этот класс был как бы введен для обработки этих случаев «Проверить, действительно ли присутствует значение». В противном случае, поскольку вы говорите: «мы не можем использовать null в качестве значения по умолчанию», я не вижу, что еще вы могли бы сделать, кроме как определить ненулевое значение по умолчанию.

3. Что касается того, почему это не очень хорошая идея: на мой взгляд, речь идет в основном о написании понятного и поддерживаемого кода. Представьте, что кому-то еще придется работать с этим кодом и изменять его в будущем. Сразу ли этот человек поймет, что эта строковая переменная имеет специальное значение, обозначающее «Значение не установлено», которое ему нужно обрабатывать особым образом? Я почему-то сомневаюсь в этом. Однако, сталкиваясь с необязательным, каждый программист Java должен знать, что это означает, что значения может не быть, что эти случаи необходимо обрабатывать, как он может проверить это с помощью метода isPresent() по умолчанию.

4. Мне это кажется дополнительной работой. Возможно, лучшим решением является представление вашего значения с помощью типа ( Optional может работать для вас или эквивалента C #), это позволит компилятору обеспечить корректность в зависимости от того, было ли значение задано пользователем или нет. Скорее всего, ваша проблема в другом месте, например, позволяя пользователю в первую очередь указывать пустое значение.

5. Спасибо тебе, Гэвин, и ВПЕРЕД, ПАУКИ. Вы показали мне хороший механизм, однако я использую C #. Я использовал Java в качестве тега, потому что я считаю, что это более архитектурная концепция или «чистый код». Для понятного кода есть возможность записать это значение корзины по умолчанию в виде const string , чтобы оно было более удобным и понятным (на самом деле это было предложение моего коллеги в конце обсуждения).

Ответ №1:

Необязательно

Можно использовать необязательный.

Возвращает пустой необязательный экземпляр. Для этого необязательного значения нет.

Примечание по API:

Хотя это может показаться заманчивым, избегайте проверки, является ли объект пустым, сравнивая с == с экземплярами, возвращаемыми Option.empty() . Нет никакой гарантии, что это синглтон. Вместо этого используйте isPresent() .

Ссылка: необязательно

Пользовательская escape-последовательность, разделяемая сервером и клиентом

  1. Определите значение по умолчанию
  2. Когда пользователь вводит значение по умолчанию, экранируйте значение пользователя

Используйте символ маркера

  1. Всегда определяйте первый символ как символ маркера
  2. Примите решение на основе этого символа и удалите этот символ для любого фактического сравнения
  3. Определите четкие границы для проверки, поскольку распространение этого символа по нескольким абстракциям может привести к проблемам с обслуживанием кода.

Ответ №2:

Небольшое уточнение «Это непрофессионально»: это часто плохая идея, потому что

  • это приводит к потере памяти, если она не является константой (по крайней мере, в Java — конечно, если вы не работаете с очень ограниченным пространством, которое незначительно).
  • Даже будучи постоянным, это может привести к двусмысленности, если у вас будет больше классов, пакетов или проектов («Было ли это NO_INPUT, INPUT_NOT_PROVIDED, INPUT_NONE?»)
  • обычно это признак того, что в проектной документации не будет стандартизированного определения с привязкой к области действия_marker_character, как предложено в других ответах
  • это вносит двусмысленность в то, как решать, был ли предоставлен ввод или нет

В итоге у вас либо будет много разных NO_INPUT констант в разных классах, либо вы получите самодельный SthUtility класс, который определяет одну константу SthUtility.NO_INPUT и статический метод boolean SthUtility.isInputEmpty(...) , который сравнивает заданный ввод с этой константой, что в основном является изобретением Optional . И вы будете копировать-вставлять этот один класс в каждый из ваших проектов.

Комментарии:

1. Это ответ, которого я ожидал. Спасибо.

Ответ №3:

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

 String value = "";
// true only if length == 0
if (value.isEmpty()) {
    System.out.println("Value is empty");
}

String value = " ";
// true if empty or contains only white space
if (value.isBlank()) {
   System.out.println("Value is blank");
}
 

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