Что такое магическое число и почему оно плохо? [закрыто]

514

Что такое магическое число?

Почему этого следует избегать?

Есть ли случаи, когда это уместно?

Адам Дэвис
источник
2
Вы избегаете магических чисел, потому что другие люди, просматривающие ваш код, могут не понимать, почему вы делаете то, что делаете ... например, const myNum = 22; const number = myNum / 11;сейчас мои 11 могут быть людьми или бутылками пива или чем-то еще, поэтому вместо этого я бы изменил 11 на постоянную такие как жители.
JuicY_Burrito
Использование магических чисел в атрибутах неизбежно, поэтому я думаю, что это уместно.
donatasj87

Ответы:

575

Магическое число - это прямое использование числа в коде.

Например, если у вас есть (на Java):

public class Foo {
    public void setPassword(String password) {
         // don't do this
         if (password.length() > 7) {
              throw new InvalidArgumentException("password");
         }
    }
}

Это должно быть изменено на:

public class Foo {
    public static final int MAX_PASSWORD_SIZE = 7;

    public void setPassword(String password) {
         if (password.length() > MAX_PASSWORD_SIZE) {
              throw new InvalidArgumentException("password");
         }
    }
}

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

JDK полон примеров как в Integer, так Characterи Mathклассов.

PS: инструменты статического анализа, такие как FindBugs и PMD, обнаруживают использование магических чисел в вашем коде и предлагают рефакторинг.

Марсио Агияр
источник
175
0 и 1 являются исключениями из этого правила.
Джонатан Паркер
24
@Kirill: Если вы ожидаете, что определение «Сто процентов» изменится, тогда да. Лучшим подходом было бы иметь переменную от того, что она есть, к тому, что она представляет, то есть public static final MAX_DOWNLOAD_PERCENTAGE = 100. Хотя даже это не имело бы смысла, потому что «100 процентов» очень хорошо определено. С другой стороны, тот факт, что пароли могут содержать не более 7 символов, не определяется глобально и фактически отличается, так что это кандидат на переменную.
Майкл Стум
40
@ Джонатан Паркер, за исключением случаев, когда они не ( TRUE/ FALSE)
Брендан Лонг
82
Тот факт, что магическое число никогда не изменится, не означает, что его нельзя заменить константой. Мой код полон глобальных констант, таких как HzPerMHz и msecPerSecond. Они никогда не изменятся, но они проясняют смысл и обеспечивают некоторую защиту от опечаток.
Жанна Пиндар
43
@MarcusJ Ты не мог быть более неправым. Это не вопрос мнений, но многолетний опыт программистов. Я не могу сказать вам, сколько раз за последние 40 лет программирования я проклинал предыдущего программиста, который не определял константу, поэтому я обнаружил только прямое использование числа, которое нужно было понять во время обслуживания кода. , где-то в большом количестве кода, смысл которого был бы ясен при определении такой константы. Любой другой старший программист также будет иметь несколько страшных историй в этом направлении.
ToolmakerSteve
146

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

Например, допустим, у вас есть страница, на которой отображаются последние 50 заказов на обзорной странице «Ваши заказы». 50 - это магическое число, потому что оно не установлено стандартом или соглашением, это число, которое вы создали по причинам, указанным в спецификации.

Теперь у вас есть 50 в разных местах - ваш SQL-скрипт ( SELECT TOP 50 * FROM orders), ваш веб-сайт (ваши последние 50 заказов), логин вашего заказа ( for (i = 0; i < 50; i++)) и, возможно, многие другие места.

Теперь, что происходит, когда кто-то решает изменить 50 на 25? или 75? или 153? Теперь вам нужно заменить 50 во всех местах, и вы, скорее всего, пропустите это. Поиск / замена может не работать, потому что 50 может использоваться для других целей, а слепая замена 50 на 25 может иметь некоторые другие плохие побочные эффекты (т. Е. Ваш Session.Timeout = 50звонок, который также установлен на 25, и пользователи начинают сообщать о слишком частых тайм-аутах).

Кроме того, код может быть сложным для понимания, т. Е. « if a < 50 then bla» - если вы столкнетесь с этим в середине сложной функции, другие разработчики, не знакомые с кодом, могут спросить себя «WTF - 50 ???»

Вот почему лучше иметь такие неоднозначные и произвольные числа ровно в 1 месте - " const int NumOrdersToDisplay = 50", потому что это делает код более читабельным (" if a < NumOrdersToDisplay", это также означает, что вам нужно только изменить его в 1 четко определенном месте.

Места, в которых подходят магические числа, - это все, что определяется стандартом, т. Е. SmtpClient.DefaultPort = 25Или TCPPacketSize = whatever(не уверен, стандартизировано ли это). Кроме того, все, что определено только в 1 функции, может быть приемлемым, но это зависит от контекста.

Майкл Стум
источник
18
Даже если это не может измениться, это все равно плохая идея, потому что не ясно, что происходит.
Лорен Печтел
11
Это не всегда неясно. SmtpClient.DefaultPort = 25возможно ясно эр чем SmtpClient.DefaultPort = DEFAULT_SMTP_PORT.
user253751
4
@immibis Я предполагаю, что предполагается, что нет абсолютно никакого другого кода, который использует концепцию DEFAULT_SMTP_PORT. Если порт SMTP по умолчанию для этого приложения изменен, его необходимо будет обновить в нескольких местах, что может привести к несогласованности.
Расс Брэдберри
3
Также сложнее найти все случаи использования - вам придется искать по 25всему приложению и убедиться, что вы изменяете только вхождения, 25которые относятся к порту SMTP, а не 25, например ширину столбца таблицы или число. записей для отображения на странице.
Майкл Стум
2
В этом примере я ожидаю, что код будет использовать SmtpClient.DefaultPort, а не 25. Так что вам просто нужно изменить его в одном месте. И номер порта, скорее всего, останется прежним, это не случайный магический номер, а номер, назначенный IANA.
njsg
34

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

В нем подробно рассказывается обо всех способах ссылки на магические числа. Вот цитата о магическом числе как плохой практике программирования

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

somas1
источник
8
Хороший пример RTFW :)
Ева
Я бы сказал, что ответ далеко не полный.
Скив
25

Волшебный номер против. Символическая константа: когда заменить?

Магия: неизвестная семантика

Символическая константа -> Обеспечивает как правильный семантический, так и правильный контекст для использования

Семантическая: смысл или цель вещи.

«Создайте константу, назовите ее после значения и замените ее числом». - Мартин Фаулер

Во-первых, магические числа - это не просто числа. Любое базовое значение может быть «волшебным». Базовые значения - это объекты манифеста, такие как целые числа, вещественные числа, числа с плавающей точкой, числа с плавающей запятой, даты, строки, логические значения, символы и т. Д. Проблема заключается не в типе данных, а в «магическом» аспекте значения, как это показано в нашем коде.

Что мы подразумеваем под "магией"? Чтобы быть точным: «магией» мы намереваемся указать на семантику (значение или цель) значения в контексте нашего кода; что это неизвестно, непостижимо, неясно или сбивает с толку. Это понятие "магия". Базовое значение не является магическим, когда его семантическое значение или цель существования быстро и легко узнаются, ясны и понятны (не путаются) из окружающего контекста без специальных вспомогательных слов (например, символической константы).

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

Полезные определения

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

основы

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

  1. Одиночное базовое значение (например, число), значение которого неизвестно, непознаваемо, неясно или запутано.
  2. Базовое значение (например, число) в контексте, но его значение остается неизвестным, непознаваемым, неясным или запутанным.

Общая зависимость «волшебства» заключается в том, что одиночное базовое значение (например, число) не имеет общеизвестной семантики (например, Pi), но имеет локально известную семантику (например, вашу программу), которая не совсем понятна из контекста или может быть злоупотреблена в хорошем или плохом контексте (ах).

Семантика большинства языков программирования не позволит нам использовать отдельные базовые значения, кроме (возможно) в качестве данных (то есть таблиц данных). Когда мы сталкиваемся с «магическими числами», мы обычно делаем это в контексте. Следовательно, ответ на

"Заменить ли это магическое число на символическую константу?"

является:

«Как быстро вы сможете оценить и понять семантическое значение числа (его цель присутствия) в его контексте?»

Вид магии, но не совсем

Имея в виду эту мысль, мы можем быстро увидеть, что число, такое как Pi (3.14159), не является «магическим числом», если помещено в соответствующий контекст (например, 2 x 3,14159 x радиуса или 2 * Pi * r). Здесь число 3.14159 мысленно распознается как Пи без символического идентификатора константы.

Тем не менее, мы обычно заменяем 3.14159 символьным постоянным идентификатором, таким как Pi, из-за длины и сложности числа. Аспекты длины и сложности числа Pi (в сочетании с необходимостью в точности) обычно означают, что символический идентификатор или константа менее подвержены ошибкам. Признание «Пи» в качестве имени является просто удобным бонусом, но не является основной причиной наличия константы.

Тем временем: обратно на ранчо

Оставляя в стороне общие константы, такие как Pi, давайте сосредоточимся в первую очередь на числах с особыми значениями, но эти значения ограничены вселенной нашей программной системы. Такое число может быть «2» (как базовое целочисленное значение).

Если я использую число 2 само по себе, мой первый вопрос может быть таким: что означает «2»? Значение «2» само по себе неизвестно и непостижимо без контекста, что делает его использование неясным и запутанным. Хотя наличие только 2 в нашем программном обеспечении не произойдет из-за языковой семантики, мы хотим видеть, что само по себе «2» не несет никакой особой семантики или очевидной цели в одиночестве.

Давайте поместим нашу одиночную «2» в контекст:, padding := 2где контекст - «Контейнер GUI». В этом контексте значение 2 (в виде пикселей или другой графической единицы) предлагает нам быстрое предположение о его семантике (значение и цель). Мы могли бы остановиться здесь и сказать, что 2 в этом контексте хорошо, и нам больше ничего не нужно знать. Однако, возможно, в нашей программной вселенной это еще не все. Это еще не все, но "padding = 2" как контекст не может раскрыть это.

Давайте далее притворимся, что 2 в качестве отступа пикселей в нашей программе имеет разновидность «default_padding» во всей нашей системе. Поэтому написание инструкции padding = 2недостаточно хорошо. Понятие «дефолт» не раскрывается. Только когда я пишу: padding = default_paddingкак контекст, а затем в другом месте: default_padding = 2я полностью осознаю лучшее и более полное значение (семантическое и целевое) значения 2 в нашей системе.

Пример выше довольно хорош, потому что «2» может быть чем угодно. Только когда мы ограничиваем диапазон и область понимания «моей программой», где 2 - это часть default_paddingGUI UX «моей программы», мы наконец понимаем «2» в соответствующем контексте. Здесь «2» - это «магическое» число, которое переводится в символическую константу default_paddingв контексте GUI UX «моей программы», чтобы его можно было использовать, как это default_paddingбыстро понимается в более широком контексте прилагаемого кода.

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

Идти дальше

Числа на шкале также могут иметь семантику. Например, представьте, что мы делаем игру D & D, где у нас есть понятие монстра. Наш монстр объект имеет функцию life_force, которая называется целым числом. Числа имеют значения, которые невозможно понять или понять без слов, чтобы придать смысл. Таким образом, мы начинаем с произвольного высказывания:

  • full_life_force: INTEGER = 10 - очень живой (и невредимый)
  • imum_life_force: INTEGER = 1 - едва жив (очень больно)
  • мертвый: INTEGER = 0 - мертвый
  • нежить: INTEGER = -1 - Мин нежити (почти мертвый)
  • зомби: INTEGER = -10 - Макс нежити (очень нежить)

Исходя из символических констант, приведенных выше, мы начинаем получать мысленную картину живости, мертвости и «нежити» (и возможных последствий или последствий) для наших монстров в нашей игре D & D. Без этих слов (символических констант) у нас останутся только числа в диапазоне от -10 .. 10. Просто диапазон без слов оставляет нас в некоторой путанице и, возможно, с ошибками в нашей игре, если разные части игры зависят от того, что этот диапазон чисел означает для различных операций, таких как attack_elvesили seek_magic_healing_potion.

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

Вывод

Давайте рассмотрим, какие вопросы мы должны задать:

У вас может быть магическое число, если ...

  1. Может ли базовое значение иметь особое значение или цель в вашей вселенной программного обеспечения?
  2. Может ли специальное значение или цель быть неизвестными, непознаваемыми, неясными или запутанными, даже в соответствующем контексте?
  3. Может ли правильное базовое значение неправильно использоваться с плохими последствиями в неправильном контексте?
  4. Может ли неправильное базовое значение правильно использоваться с плохими последствиями в правильном контексте?
  5. Имеет ли базовое значение семантические или целевые отношения с другими базовыми ценностями в конкретных контекстах?
  6. Может ли базовое значение существовать в более чем одном месте в нашем коде с различной семантикой в ​​каждом, что вызывает у нашего читателя путаницу?

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

В конце ответом на замену является ответ на меру (по вашему мнению) силы или слабости читателя, чтобы установить связь (например, «получить его»). Чем быстрее они понимают смысл и цель, тем меньше у вас «волшебства».

ЗАКЛЮЧЕНИЕ: заменяйте базовые значения символическими константами только тогда, когда магия достаточно велика, чтобы затруднять обнаружение ошибок, возникающих в результате путаницы.

Larry
источник
1
Спасибо. Хотя инструменты статического анализа, которые продолжают устанавливать мои коллеги, продолжают жаловаться на магические числа, но как инструмент должен понимать семантику? В результате ВСЕ базовые значения заменяются символическими константами. Как я согласен с вашим выводом, я считаю, что это не идеально.
Чоме
17

Магическое число - это последовательность символов в начале формата файла или протокола обмена. Этот номер служит проверкой работоспособности.

Пример: Откройте любой файл GIF, вы увидите в самом начале: GIF89. «GIF89» - это магическое число.

Другие программы могут читать первые несколько символов файла и правильно идентифицировать GIF-файлы.

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

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

Магические числа все еще полезны.

Брайан Р. Бонди
источник
13
Я не думаю, что это магическое число, на которое он ссылался
Марсио Агиар
4
Возможно, вам следует удалить добавленные вами теги «file-format» и «network», потому что он явно не говорит о подобных магических числах.
Лэндон
9
Все еще очень полезно знать, что магические числа могут относиться не только к проблеме кода. -Адам
Адам Дэвис
3
Если тема гласила: «Что такое магическое число с точки зрения исходного кода», то теги быть не должны. Но он не уточнил это. Так что иметь дополнительную информацию - это хорошо. Я думаю, что Кайл, Лэндон и Марсио не правы.
Брайан Р. Бонди
4
Также не было способа определить, кого он ищет. Так как я был первым постом, я не мог догадаться, какой он искал.
Брайан Р. Бонди
12

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

Это плохо по той же причине, что SPOT (Single Point of Truth) хорош: если вы захотите изменить эту константу позже, вам придется искать код, чтобы найти каждый экземпляр. Это также плохо, потому что другим программистам может быть непонятно, что представляет это число, отсюда и «магия».

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

Ник Реталлак
источник
Можете ли вы более конкретно сказать, почему устранение чисел магнита не всегда хорошо?
Марсио Агиар
В математических формулах, таких как e ^ pi + 1 = 0
Джаред Апдайк
5
Марсио: Когда ты делаешь такие вещи, как «const int EIGHT = 8;» и затем требования меняются, и в итоге вы получаете «const int EIGHT = 9;»
jmucchiello
6
Извините, но это просто пример неправильного именования или базового использования константы.
Kzqai
1
@MarcioAguiar: на некоторых платформах выражение вроде (foo[i]+foo[i+1]+foo[i+2]+1)/3может быть вычислено намного быстрее, чем цикл. Если кто-то заменит 3код без переписывания кода в виде цикла, то тот, кто увидит ITEMS_TO_AVERAGEопределенное как, 3может подумать, что он может изменить его 5и получить код, усредняющий больше элементов. В отличие от этого, кто-то, кто посмотрел бы на выражение с литералом 3, понял бы, что 3представляет количество элементов, суммируемых вместе.
суперкат
10

Магическое число также может быть числом со специальной жестко закодированной семантикой. Например, однажды я видел систему, в которой идентификаторы записей> 0 обрабатывались нормально, сам 0 был «новой записью», -1 был «это корень», а -99 был «это было создано в корне». 0 и -99 приведут к тому, что WebService предоставит новый идентификатор.

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

Возможно, 22, 7, -12 и 620 тоже считаются магическими числами. ;-)

Сёрен Куклау
источник
10

Проблема, о которой не упоминалось при использовании магических чисел ...

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

И затем, конечно же, вам нужно изменить значение ... только для одной цели.


источник
Это выглядит не слишком вероятным, если говорить о числах (по крайней мере, не для меня), но я наткнулся на это со строками, и это хит: сначала вы должны прочитать много кода, чтобы увидеть, где он используется, чем вы. Должен заметить, что он используется для разных вещей ... не мое любимое занятие.
Томислав Накич-Альфиревич
4

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

Кайл Кронин
источник
3

Я всегда использовал термин «магическое число» по-разному, как неясное значение, хранимое в структуре данных, которое можно проверить как быструю проверку достоверности. Например, файлы gzip содержат 0x1f8b08 в качестве первых трех байтов, файлы классов Java начинаются с 0xcafebabe и т. Д.

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

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

DGentry
источник
2

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

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

Роб Ролник
источник
1
На мой взгляд, запах магического кода относится именно к необъяснимым константам. Пока вы помещаете их в именованную константу, это не должно быть проблемой.
Дон Киркби
2

Как насчет инициализации переменной в начале класса значением по умолчанию? Например:

public class SomeClass {
    private int maxRows = 15000;
    ...
    // Inside another method
    for (int i = 0; i < maxRows; i++) {
        // Do something
    }

    public void setMaxRows(int maxRows) {
        this.maxRows = maxRows;
    }

    public int getMaxRows() {
        return this.maxRows;
    }

В этом случае 15000 - это магическое число (согласно CheckStyles). Для меня установка значения по умолчанию в порядке. Я не хочу делать:

private static final int DEFAULT_MAX_ROWS = 15000;
private int maxRows = DEFAULT_MAX_ROWS;

Это затрудняет чтение? Я никогда не думал об этом, пока не установил CheckStyles.

Аскалона
источник
Я думаю, что это будет хорошо, если конструктор инициализирует значение. В противном случае, если значение инициализируется вне конструктора, я просто вижу его как трудность и что-то более сложное для чтения.
Томас Эдинг
Я думаю, что static finalконстанты излишни, когда вы используете их в одном методе. finalПеременная , объявленная в верхней части метода является более удобным для чтения ИМХО.
Ева
0

@ eed3si9n: Я бы даже предположил, что «1» - это магическое число. :-)

Принцип, связанный с магическими числами, заключается в том, что каждый факт, с которым работает ваш код, должен быть объявлен ровно один раз. Если вы используете магические числа в своем коде (например, пример длины пароля, который дал @marcio, вы легко можете в конечном итоге продублировать этот факт, и когда ваше понимание этого факта изменится, у вас возникнет проблема с обслуживанием.

Эндрю
источник
5
Код IOW должен быть написан так:factorial n = if n == BASE_CASE then BASE_VALUE else n * factorial (n - RECURSION_INPUT_CHANGE); RECURSION_INPUT_CHANGE = 1; BASE_CASE = 0; BASE_VALUE = 1
Томас Эдинг
0

Как насчет возвращаемых переменных?

Мне особенно сложно при реализации хранимых процедур .

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

int procGetIdCompanyByName(string companyName);

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

int procGetIdCompanyByName(string companyName, bool existsCompany);

Кстати, что он должен вернуть, если компании не существует? Хорошо: он установит existesCompany как false , но также вернет -1.

Другой вариант - сделать две отдельные функции:

bool procCompanyExists(string companyName);
int procGetIdCompanyByName(string companyName);

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

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

Суть в следующем: что вы думаете об использовании такого рода «магических чисел», которые относительно известны и безопасны, чтобы сказать, что что-то не удалось или что-то не существует?

Oskytar
источник
В этом конкретном случае, если в документации функции указано, что отрицательное возвращаемое значение означает, что компания не была найдена, то нет никакой причины использовать константу.
Винсент Фурмонд
-1

Другое преимущество извлечения магического числа в качестве константы дает возможность четко документировать деловую информацию.

public class Foo {
    /** 
     * Max age in year to get child rate for airline tickets
     * 
     * The value of the constant is {@value}
     */
    public static final int MAX_AGE_FOR_CHILD_RATE = 2;

    public void computeRate() {
         if (person.getAge() < MAX_AGE_FOR_CHILD_RATE) {
               applyChildRate();
         }
    }
}
jguiraud
источник