Использование магических строк или констант при обработке пунктуации?

Мы делаем много лексической обработки с произвольными строками, которые включают произвольные знаки препинания. Я разделился относительно того, использовать ли магические символы/строки или символические константы.

Примеры следует читать как независимые от языка, хотя большинство из них написаны на Java.

Есть явные примеры, когда пунктуация играет семантическую роль и должна быть определена как константа:

File.separator не "/" или "\\"; // легко, так как это зависит от ОС

и я пишу XML_PREFIX_SEPARATOR = ":";

Однако допустим, мне нужно заменить все примеры "" пустой строкой ``. Я могу написать:

s = s.replaceAll("\"\"", "");

or

s = s.replaceAll(S_QUOT+S_QUOT, S_EMPTY);

(Я определил все распространенные знаки препинания как S_FOO (строка) и C_FOO (символ))

В пользу магических строк/символов:

  1. Это короче
  2. Естественно читать (иногда)
  3. Именованные константы могут быть не знакомы (C_APOS против '\'')

В пользу констант

  1. Труднее сделать опечатки (например, противопоставить "''" + '"' S_APOS+S_APOS + C_QUOT)
  2. Это устраняет проблемы с экранированием. Должно ли регулярное выражение быть "\\s+", "\s+" или "\\\\s+"?
  3. Легко найти код по знакам препинания

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


person peter.murray.rust    schedule 27.11.2009    source источник


Ответы (2)


Если определения могут меняться со временем или между установками, я стараюсь помещать эти вещи в файл конфигурации и получать информацию при запуске или по запросу (в зависимости от ситуации). Затем предоставьте статический класс с интерфейсом только для чтения и четкими именами свойств для предоставления информации системе.

Использование может выглядеть так:

s = s.replaceAll(CharConfig.Quotation + CharConfig.Quotation, CharConfig.EmtpyString);
person Fredrik Mörk    schedule 27.11.2009
comment
Я рад видеть, что я не одинок в том, что время от времени выступаю за такой уровень многословия. - person peter.murray.rust; 27.11.2009

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

s.replace("String", " ");

Чем:

s.replace("String", S_SPACE);

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

Что касается таких вещей, как XML_PREFIX_SEPARATOR или FILE_SEPARATOR, вам, вероятно, никогда не придется иметь дело с такими константами, поскольку вы должны использовать библиотеку, которая сделает всю работу за вас. Например, вы не должны писать от руки: dir + FILE_SEPARATOR + filename, а должны звонить: file_system_library.join(dir, filename) (или любой аналог, который вы используете).

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

person Edan Maor    schedule 27.11.2009
comment
Насчет библиотек полностью согласен. Я использую их и пишу их. Однако бывают случаи, когда мне нужен доступ к примитивам. - person peter.murray.rust; 27.11.2009
comment
@peter.murray.rust: Да, определенно есть много случаев, когда вам действительно нужны примитивы (например, при написании библиотеки!). Но я заметил, что много раз, когда люди спрашивают о примитивах, ответом является более высокий уровень абстракции, поэтому мне нравится предлагать это как еще один вариант. - person Edan Maor; 27.11.2009