Возвращает нулевой плохой дизайн? [закрыто]

127

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

псевдокод:

variable x = object.method()
if (x is null) do something
Koen
источник
13
Подробно: где эти люди, которые говорят, что это плохо? Ссылки?
jcollum
2
Если метод - это то, что вы контролируете, вы можете использовать модульные тесты, чтобы убедиться, что он никогда не возвращает null, в противном случае я не понимаю, почему было бы плохой практикой проверять, является ли он null после этого вызова; это может быть плохой практикой для этого метода возвращать null, но вы должны защитить свой код
BlackTigerX
9
Создание исключений только потому, что нет данных, которые нужно вернуть, невероятно раздражает. Обычный поток программы не должен вызывать исключений.
Thorarin
4
@ Дэвид: Я действительно так сказал. Если метод должен возвращать данные, но их нет, значит, что-то тоже пошло не так. Это не нормальный поток программы :)
Торарин,
2
@Thorarin: «нормальный» поток программы - довольно растяжимое понятие: не совсем прочная основа для аргументации.
Томислав Накич-Альфиревич

Ответы:

206

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

Например, если бы я определил в Java метод, возвращающий коллекцию, я бы обычно предпочел возвращать пустую коллекцию (т.е. Collections.emptyList()), а не ноль, поскольку это означает, что мой клиентский код чище; например

Collection<? extends Item> c = getItems(); // Will never return null.

for (Item item : c) { // Will not enter the loop if c is empty.
  // Process item.
}

... что чище, чем:

Collection<? extends Item> c = getItems(); // Could potentially return null.

// Two possible code paths now so harder to test.
if (c != null) {
  for (Item item : c) {
    // Process item.
  }
}
Адамский
источник
6
Да, это лучше, чем возвращать null и надеяться, что клиент не забудет разобраться с делом.
djna
10
Я с радостью согласен с тем, что возвращать null - это безумие, когда его используют вместо пустых контейнеров (или строк). Однако это не обычный случай.
MSalters
2
+1 за шаблон Null Object для меня тоже. Кроме того, когда я действительно хочу вернуть null, я назвал метод, например, getCustomerOrNull (), чтобы сделать его явным. Я думаю, что метод назван хорошо, когда читатель не хочет смотреть на реализацию.
Майк Валенти,
4
Комментарий «// Теперь два возможных пути кода» неверен; в любом случае у вас есть два пути кода. Однако с нулевым объектом Collection в вашем первом примере путь «нулевого» кода короче. Однако у вас все еще есть два пути, и вам все еще нужно проверить два пути.
Frerich Raabe
1
@MSalters - возможно, каждая переменная в объектно- ориентированных языках nullявляется «контейнером», который содержит ноль или один указатель на объекты. (Именно так Maybeв этих случаях он явно моделируется Haskell , и тем лучше для этого.)
Анджей Дойл
71

Вот причина.

В « Чистом коде» Роберта Мартина он пишет, что возвращение нуля - плохой дизайн, когда вместо этого можно вернуть, скажем, пустой массив. Поскольку ожидаемый результат - это массив, почему бы и нет? Это позволит вам перебирать результат без каких-либо дополнительных условий. Если это целое число, может быть достаточно 0, если это хеш, пустой хеш. и т.п.

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

Макс Черняк
источник
2
Это шаблон нулевого объекта, упомянутый в этом ответе: stackoverflow.com/questions/1274792/…
Скотт Дорман
Идея здесь в том, что в случае ошибки вы возвращаете пустую / пустую версию любого типа объекта, который вы бы обычно возвращали. Например, для этих случаев подойдет пустой массив или строка. Возврат «NULL» уместен, когда вы обычно возвращаете указатель (поскольку NULL по сути является пустым указателем). Возврат NULL при ошибке из функции, которая обычно возвращает, скажем, хеш, может сбивать с толку. Некоторые языки справляются с этим лучше, чем другие, но в целом согласованность - лучшая практика.
bta
Вы не обязательно вернетесь к ошибке, если только ошибка каким-либо образом не управляет потоком (что не является хорошей практикой) или абстрагируется в API или интерфейсе. Ошибки могут распространяться на любой уровень, на котором вы решите их отловить, поэтому вам не нужно иметь дело с ними в контексте вызова. По умолчанию они совместимы с шаблоном нулевого объекта.
Макс Черняк
К сожалению, вызывающий код не всегда учитывает случай пустой коллекции (как не учитывает случай null). Это может быть, а может и не быть проблемой.
Шридхар Сарнобат
38

Хорошее использование возврата null:

  • Если null является допустимым функциональным результатом, например: FindFirstObjectThatNeedsProcessing () может вернуть null, если не найден, и вызывающий должен проверить соответственно.

Плохое использование: попытка заменить или скрыть исключительные ситуации, такие как:

  • catch (...) и вернуть null
  • Ошибка инициализации зависимости API
  • Недостаточно места на диске
  • Неверные входные параметры (ошибка программирования, входные данные должны быть очищены вызывающим абонентом)
  • и т.д

В этих случаях более адекватным является создание исключения, поскольку:

  • Возвращаемое значение null не дает значимой информации об ошибке
  • Непосредственный вызывающий, скорее всего, не может обработать состояние ошибки
  • Нет гарантии, что вызывающий абонент проверяет нулевые результаты

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

  • Неверное имя пользователя / пароль (или любые введенные пользователем данные)
  • Разрыв петель или нелокальных переходов
ZeroConcept
источник
7
«Неверное имя пользователя» кажется хорошей причиной исключения.
Тило
11
Пользователи, вводящие неверные логины / пароли, не должны рассматриваться как исключительные условия, являющиеся частью нормальной работы программы. Однако отказ системы аутентификации (например, активный каталог) является исключительным условием.
ZeroConcept,
2
Я бы сказал, это зависит от boolean login(String,String)AuthenticationContext createAuthContext(String,String) throws AuthenticationException
обстоятельств
1
В вашем примере, если нет первого объекта, который требует обработки, то есть два разумных способа справиться с этим случаем. Первый - это шаблон «Нулевой объект». Создайте последний подкласс, представляющий несуществующую версию класса. Он имеет разумные значения по умолчанию и выдает исключения, когда запрашиваются бессмысленные действия. Другой метод - вариант. Это то, что доступно в Java8 и Scala. Любой из них показывает намерение разработчиков. null не может показать намерение, потому что он имеет слишком много возможных значений. ** Отображение намерения ** - самый важный аспект кода.
scott m gardner
29

Да, возвращение NULL - ужасный дизайн в объектно-ориентированном мире. Вкратце, использование NULL приводит к:

  • специальная обработка ошибок (вместо исключений)
  • неоднозначная семантика
  • медленно, а не быстро
  • компьютерное мышление вместо объектного мышления
  • изменяемые и неполные объекты

Подробное объяснение можно найти в этом сообщении в блоге: http://www.yegor256.com/2014/05/13/why-null-is-bad.html . Подробнее в моей книге « Элегантные объекты» , раздел 4.1.

yegor256
источник
2
Я полностью согласен. Мне даже не нравится шаблон нулевого объекта, который кажется тактикой задержки «прикрытия». Либо ваш метод всегда будет успешным, либо нет. Если всегда должно получаться, то бросай. Если это не удастся, разработайте метод так, чтобы потребитель знал, например, bool TryGetBlah(out blah)или FirstOrNull()или MatchOrFallback(T fallbackValue).
Люк Пуплетт 02
Мне тоже не нравится return null. Вы отделяете основную причину от симптома, что затрудняет отладку. Либо вызовите исключение (быстро завершите работу), либо вызовите метод проверки, который сначала возвращает логическое значение (например isEmpty()), и только если оно истинно, затем вызовите метод. Люди возражают против второго, говорят, что у него более низкая производительность, но, как говорит философия Unix, «цените человеческое время по сравнению с машинным временем» (то есть тривиально более низкая производительность тратит меньше времени, чем разработчики, отлаживающие код, который дает ложные ошибки).
Sridhar Sarnobat 05
22

Кто сказал, что это плохой дизайн?

Проверка на нули - обычная практика, даже поощряемая, иначе вы рискуете повсюду получить NullReferenceExceptions. Лучше аккуратно обработать ошибку, чем генерировать исключения, когда в этом нет необходимости.

Brandon
источник
11
+1. Код, который генерирует исключения для проблем, которые можно устранить на месте, меня огорчает.
jkeys
6
Как вам грустно, когда программисты забывают проверять нули, а затем получают загадочные исключения нулевого указателя? Проверенные исключения, когда компилятор напоминает пользователю, что они не работали с ошибочными условиями, избегают такого класса ошибок кодирования.
djna
3
@djna: Думаю, это тоже печально, но я обнаружил, что кодеры того же типа, которые «забывают» проверять наличие нулей, - это те, кто при работе с проверенными исключениями часто в конечном итоге их проглатывает.
Рэнди поддерживает Монику
5
Легче обнаружить наличие пустого блока catch, чем отсутствие нулевой проверки.
Престон,
20
@ Престон: Я категорически не согласен. Отсутствие нулевой проверки вы сразу заметите, когда она выйдет из строя. Проглоченные исключения могут на долгие годы порождать таинственные и тонкие ошибки ...
Беска
18

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

Возврат null из метода CreateWidget () кажется плохим.

Возврат null из метода FindFooInBar () кажется прекрасным.

jcollum
источник
4
Подобно моему соглашению: запросы по Create... одному элементу - возвращает новый экземпляр или бросает ; Get...возвращает ожидаемый существующий экземпляр или выбрасывает ; GetOrCreate...возвращает существующий экземпляр или новый экземпляр, если его нет, или выбрасывает ; Find...возвращает существующий экземпляр, если он существует, илиnull . Для запросов коллекции - Get... всегда возвращает коллекцию, которая пуста, если совпадающие элементы не найдены.
Иоганн Герелл
NULL плох по причинам, указанным в ответе yegor256 и hakuinin, возвращение действительного, но пустого объекта упрощает рассуждение в
целом
12

Его изобретатель говорит, что это ошибка на миллиард долларов!

Бахадыр Яган
источник
10

Это зависит от языка, который вы используете. Если вы работаете в таком языке, как C #, где идиоматический способ указать отсутствие значения - это вернуть null, тогда возврат null - хороший вариант, если у вас нет значения. В качестве альтернативы, в таких языках, как Haskell, которые идиоматически используют монаду Maybe для этого случая, возвращение null было бы плохим дизайном (если бы это было вообще возможно).

Грег Бич
источник
2
+1 за упоминание возможно монады. Я считаю, что определения nullв таких языках, как C # и Java, часто перегружены и придают какое-то значение в предметной области. Если вы найдете nullключевое слово в спецификациях языка, оно просто означает «недействительный указатель». Это, вероятно, ничего не значит ни в какой проблемной области.
MattDavey
Проблема в том, что вы не знаете, «отсутствующее значение» это nullили «не инициализировано»null
CervEd
5

Если вы прочтете все ответы, станет ясно, что ответ на этот вопрос зависит от типа метода.

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

Всякий раз, когда ожидается, что метод не даст результатов, есть две категории:

  • Если возможно вернуть нейтральное значение, сделайте это .
    Пустые перечисления, строки и т. Д. - хорошие примеры
  • Если такое нейтральное значение не существует, следует вернуть null .
    Как уже упоминалось, предполагается, что метод, возможно, не даст результата, поэтому он не является исключительным и, следовательно, не должен вызывать исключение. Нейтральное значение невозможно (например: 0 не является особенно нейтральным результатом, в зависимости от программы)

Пока у нас не будет официального способа обозначить, что функция может или не может возвращать значение null, я стараюсь иметь соглашение об именах, чтобы обозначить это.
Так же, как у вас есть соглашение Try Something () для методов, которые, как ожидается, не сработают, я часто называю свои методы Safe Something () когда метод возвращает нейтральный результат вместо null.

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

Борис Калленс
источник
4

У меня есть конвенция в этой области, которая мне хорошо послужила

Для запросов по одному элементу:

  • Create...возвращает новый экземпляр или бросает
  • Get...возвращает ожидаемый существующий экземпляр или бросает
  • GetOrCreate...возвращает существующий экземпляр или новый экземпляр, если его нет, или бросает
  • Find...возвращает существующий экземпляр, если он существует, илиnull

Для запросов по сбору:

  • Get... всегда возвращает коллекцию, которая пуста, если не найдено подходящих [1] элементов

[1] с учетом некоторых критериев, явных или неявных, указанных в имени функции или в качестве параметров.

Иоганн Герелл
источник
Почему GetOne и FindOne возвращают разные результаты, если не найдены?
Владимир Вуканац
Я описал разницу. Я использую, Getкогда ожидаю, что он там будет, так что если его нет, то это ошибка, и я выброшу - мне никогда не нужно проверять возвращаемое значение. Я использую, Findесли действительно не знаю, есть он или нет - тогда мне нужно проверить возвращаемое значение.
Иоганн Герелл
3

Исключения составляют исключения обстоятельства.

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


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

Если это имеет какое-то значение, можно вернуть null:

public String getEmployeeName(int id){ ..}

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

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

public Integer getId(...){
   try{ ... ; return id; }
   catch(Exception e){ return null;}
}
Стив Б.
источник
3
Ага. Если у вас возникла ошибка, вызовите исключение.
Дэвид Торнли,
3
Это тот случай, когда требуется исключение. Если вы запрашиваете имя несуществующего сотрудника, очевидно, что что-то идет не так.
Thorarin
Я думаю, что это немного буквально, Торарин - вы, конечно, можете придраться к моему примеру, но я уверен, что вы можете представить какой-нибудь экземпляр функции, которая возвращает совпадающее значение или null, если совпадения нет. Как насчет получения значения из ключа в хеш-таблице? (в первую очередь следовало подумать об этом примере).
Стив Б.
1
Хеш-таблица, возвращающая ноль для несуществующего ключа, - это плохо. Это автоматически означает, что вы не можете сохранить null как значение без несогласованного кода.
RHSeeger
3

Это не обязательно плохой дизайн - это зависит от многих дизайнерских решений.

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

object x = GetObjectFromCache();   // return null if it's not in the cache

Если действительно всегда должен быть результат, отличный от NULL, может быть лучше выбросить исключение:

try {
   Controller c = GetController();    // the controller object is central to 
                                      //   the application. If we don't get one, 
                                      //   we're fubar

   // it's likely that it's OK to not have the try/catch since you won't 
   // be able to really handle the problem here
}
catch /* ... */ {
}
Майкл Берр
источник
2
Хотя вы можете зарегистрировать диагностическую ошибку прямо здесь, затем, возможно, повторно выбросите исключение. Иногда очень полезен сбор данных о первом отказе.
djna
Или оберните исключение в RuntimeException с диагностической информацией в строке сообщения. Храните информацию вместе.
Thorbjørn Ravn Andersen
Теперь (в 2018 году) я больше не могу соглашаться, и в таких случаях мы должны предпочитать возвращениеOptional<>
Петр Мюллер
2

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

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

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

Дрю Хоскинс
источник
2

Какие альтернативы вы видите возвращению null?

Я вижу два случая:

  • findAnItem (идентификатор). Что делать, если предмет не найден

В этом случае мы могли бы: вернуть Null или выбросить (проверенное) исключение (или, возможно, создать элемент и вернуть его)

  • listItemsMatching (критерии) что это должно возвращать, если ничего не найдено?

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

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

x = find();
x.getField();  // bang null pointer exception

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

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

DJNA
источник
3
Создание исключений для обозначения условия, которое, как ожидается, может произойти во время нормального выполнения программы, приводит к действительно уродливому коду, вроде try {x = find ()} catch (RecordNotFound e) {// делать вещи}.
Quant_dev
Возврат пустых списков - хорошее решение, но только если метод находится в контексте, который может возвращать списки. Для ситуаций "findById" вам нужно вернуть null. Мне не нравятся исключения RecordNotFound.
Тило
Так что в этом суть нашего расхождения во мнениях. На мой взгляд, нет большой разницы в красоте между x = find (); if (x = null) {work} else {do ​​stuff} и попробуй поймать. А при необходимости готов пожертвовать красотой ради корректности кода. Слишком часто в жизни я сталкиваюсь с кодом, в котором возвращаемые значения не проверяются.
djna
1

Иногда возвращение NULL является правильным решением, но особенно, когда вы имеете дело с последовательностями разного типа (массивы, списки, строки и т. Д.), Вероятно, лучше вернуть последовательность нулевой длины, поскольку она приводит к более короткому и, надеюсь, более понятному коду, не требуя при этом гораздо большего количества написания со стороны разработчика API.

Vatine
источник
1

Заставьте их вызвать другой метод постфактум, чтобы выяснить, был ли предыдущий вызов нулевым. ;-) Эй, для JDBC хватило

Дэвид Пламптон
источник
1

Основная идея этой темы - защитное программирование. То есть код против неожиданного. Есть множество разных ответов:

Адамски предлагает посмотреть на образец нулевого объекта, и этот ответ был одобрен за это предложение.

Майкл Валенти также предлагает соглашение об именах, чтобы сообщить разработчику, чего можно ожидать. ZeroConcept предлагает правильное использование Exception, если это является причиной NULL. И другие.

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

Но у нас есть 2 сценария развития.

Классы «авторские» разработчик: Автор

Классы, "потребляемые" другим (возможно) разработчиком: Разработчик

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

Если разработчик не может этого сделать, то этот класс / метод не является детерминированным. То есть, если «вызов метода» для получения объекта не выполняет то, что он «рекламирует» (например, getEmployee), это нарушает контракт.

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

Итак, учитывая, что либо NULL, либо NULL OBJECT (например, if (employee as NullEmployee.ISVALID)) необходимо проверить, и это может потребоваться с коллекцией сотрудников, то подход с нулевым объектом является лучшим подходом.

Но мне также нравится предложение Майкла Валенти назвать метод, который ДОЛЖЕН возвращать значение null, например getEmployeeOrNull.

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

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

Итак, как разработчик, я должен защищать метод от NULL. Если автор дал мне контракт, который всегда возвращает объект (всегда возвращает NULL OBJECT), и этот объект имеет метод / свойство, с помощью которого можно проверить действительность объекта, то я бы использовал этот метод / свойство для продолжения использования объекта. , иначе объект недействителен, и я не могу его использовать.

Суть в том, что Автор класса / методов должен предоставить механизмы, которые Разработчик может использовать в своем защитном программировании. То есть более четкое намерение метода.

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

С уважением

GregJF

GregJF
источник
0

Другие варианты для этого: возврат некоторого значения, которое указывает на успех или нет (или тип ошибки), но если вам просто нужно логическое значение, которое будет указывать на успех / неудачу, возврат null для неудачи, а объект для успеха не быть менее правильным, затем вернуть истину / ложь и получить объект через параметр. Поэтому я лично не вижу ничего плохого в том, чтобы возвращать null как указание на то, что что-то пошло не так, и проверять его позже (чтобы узнать, удалось ли вам это или нет). Кроме того, слепо полагая, что ваш метод не вернет NULL, а затем основывает свой код на нем, может привести к другим, иногда трудным для поиска ошибкам (хотя в большинстве случаев это просто приведет к сбою вашей системы :), как вы будете ссылаться на 0x00000000 рано или поздно).
Другой подход - использовать исключение для указания сбоев, но здесь на самом деле гораздо больше голосов, которые говорят, что это ПЛОХОЙ метод (поскольку использование исключений может быть удобным, но имеет много недостатков).

Марцин Дептула
источник
0

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

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

Null_function @wikipedia

Сочный Скриптер
источник
0

Ну, конечно, это зависит от цели метода ... Иногда лучше было бы выбросить исключение. Все зависит от случая к случаю.

Денис Биондик
источник
0

Если код выглядит примерно так:

command = get_something_to_do()

if command:  # if not Null
    command.execute()

Если у вас есть фиктивный объект, метод execute () которого ничего не делает, и вы возвращаете его вместо Null в соответствующих случаях, вам не нужно проверять регистр Null, и вместо этого вы можете просто сделать:

get_something_to_do().execute()

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

скоро
источник
0

Для моего случая использования мне нужно было вернуть Map from метод, а затем искать определенный ключ. Но если я верну пустую карту, это приведет к NullPointerException, и тогда это не будет сильно отличаться от возврата null вместо пустой карты. Но начиная с Java8 мы могли использовать Optional . Вышеупомянутое и является причиной введения дополнительной концепции.

Аман Гупта
источник
-3

G'day,

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

Почему, черт возьми, это плохой дизайн, понятия не имею.

Изменить: это верно для языков, где у вас нет исключений, таких как C, где это было соглашением в течение многих лет.

НТН

«Avahappy,

Роб Уэллс
источник
2
Если вы не можете создать объект, вам действительно следует выбросить исключение. Если вы не можете найти объект, соответствующий какому-либо запросу, тогда верните null.
Тило
@Thilo, покажи мне, как это сделать на C, и мне будет интересно.
Роб Уэллс,
@RobWells C не является объектно-ориентированным языком, но этот вопрос помечен как "oop"
yegor256
@ yegor256 Вы правы. И я пропустил оригинальный тег ООП. Но, как сказал BS, класс в C ++ - это просто структура с добавленными некоторыми дополнительными функциями-членами и некоторым причудливым управлением памятью, происходящим внутри. Но если API должен возвращать структуру, то возвращение NUL, когда вы не можете создать структуру, часто является соглашением.
Роб Уэллс