У меня есть метод, который должен вернуть объект, если он найден.
Если это не найдено, я должен:
- вернуть ноль
- бросить исключение
- Другой
exception
error-handling
null
Роберт
источник
источник
Ответы:
Если вы всегда ожидаете найти значение, выведите исключение, если оно отсутствует. Исключение будет означать, что возникла проблема.
Если значение может отсутствовать или присутствовать, и оба они действительны для логики приложения, вернуть ноль.
Более важно: что вы делаете в других местах в коде? Последовательность важна.
источник
GetPersonById(25)
выбросит, если этот человек был удален, ноGetPeopleByHairColor("red")
вернет пустой результат. Итак, я думаю, что параметры говорят об ожиданиях.Только бросить исключение, если это действительно ошибка. Если ожидаемое поведение для объекта не существует, вернуть ноль.
В противном случае это вопрос предпочтения.
источник
Как правило, если метод должен всегда возвращать объект, тогда используйте исключение. Если вы ожидаете случайного нулевого значения и хотите обработать его определенным образом, используйте нулевое значение.
Что бы вы ни делали, я настоятельно рекомендую против третьего варианта: возвращать строку с надписью "WTF".
источник
Если null никогда не указывает на ошибку, просто верните null.
Если ноль всегда является ошибкой, тогда выдается исключение.
Если null иногда является исключением, тогда кодируйте две подпрограммы. Одна подпрограмма выдает исключение, а другая - логическую тестовую подпрограмму, которая возвращает объект в выходном параметре, а подпрограмма возвращает false, если объект не был найден.
Трудно неправильно использовать процедуру Try. Это действительно легко забыть проверить на ноль.
Так что, когда ноль является ошибкой, вы просто пишете
Когда ноль не является ошибкой, вы можете написать что-то вроде
источник
find
иfindOrFail
от Laravel EloquentTryFindObject
метода? Кортежи кажутся более ленивой парадигмой для программистов, которые не хотят тратить время на определение объекта, который инкапсулирует множество значений. То есть по сути все кортежи лежат в основе в любом случае.Я просто хотел повторить перечисленные выше варианты, добавив несколько новых:
Или вы можете объединить эти параметры:
Предоставьте несколько перегруженных версий вашего геттера, чтобы вызывающий мог решить, каким путем идти. В большинстве случаев только первый имеет реализацию алгоритма поиска, а остальные просто оборачивают первый:
Даже если вы решите предоставить только одну реализацию, вы можете захотеть использовать соглашение об именах, подобное этому, для уточнения своего контракта, и это поможет вам, если вы когда-нибудь решите добавить другие реализации.
Вы не должны злоупотреблять этим, но это может быть полезно, особенно при написании вспомогательного класса, который вы будете использовать в сотнях различных приложений со многими различными соглашениями об обработке ошибок.
источник
Expected<T> findObject(String)
гдеExpected<T>
есть функцииorNull()
,orThrow()
,orSupplied(Supplier<T> supplier)
,orDefault(T default)
. Это абстрагирует получение данных от обработки ошибокИспользуйте шаблон нулевого объекта или создайте исключение.
источник
Person somePerson = personRepository.find("does-not-exist");
предположим, что этот метод возвращает нулевой объект для идентификатораdoes-not-exist
. Что тогда будет правильным поведениемsomePerson.getAge()
? Сейчас я еще не убежден, что шаблон нулевого объекта является правильным решением для поиска сущностей.Будьте последовательны с API, который вы используете.
источник
Преимущества броска исключения:
Для более подробного объяснения с примерами, см .: http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/
источник
это зависит от того, продвигает ли ваш язык и код: LBYL (смотри, прежде чем прыгнуть) или EAFP (проще просить прощения, чем разрешения)
LBYL говорит, что вы должны проверить значения (так что возвращайте ноль)
EAFP говорит, чтобы просто попробовать операцию и посмотреть, если она потерпит неудачу (выбросить исключение)
хотя я согласен с вышесказанным .. исключения должны использоваться для исключительных ситуаций / ошибок, и возвращение нулевого значения лучше при использовании проверок.
EAFP против LBYL в Python:
http://mail.python.org/pipermail/python-list/2003-May/205182.html ( веб-архив )
источник
Просто спросите себя: «Это исключительный случай, когда объект не найден»? Если ожидается, что это произойдет в ходе обычной программы, вам, вероятно, не следует выдавать исключение (поскольку это не исключительное поведение).
Краткая версия: используйте исключения для обработки исключительного поведения, а не для управления потоком управления в вашей программе.
-Алан.
источник
Исключения связаны с проектированием по контракту.
Интерфейс объекта - это фактически контракт между двумя объектами, вызывающий должен выполнить контракт, иначе получатель может просто потерпеть неудачу с исключением. Есть два возможных контракта
1) все входные данные метода действительны, и в этом случае вы должны вернуть ноль, если объект не найден.
2) допустим только некоторый ввод, то есть тот, который приводит к найденному объекту. В этом случае вы ДОЛЖНЫ предложить второй метод, который позволяет вызывающей стороне определить, будет ли его ввод правильным. Например
ЕСЛИ И ТОЛЬКО ЕСЛИ вы предоставляете оба метода 2-го контракта, вы можете выбросить исключение, если ничего не найдено!
источник
Я предпочитаю просто возвращать нуль и полагаться на вызывающего, чтобы обработать его соответствующим образом. Исключение (из-за отсутствия лучшего слова) - если я абсолютно «уверен», этот метод вернет объект. В этом случае сбой является исключительным, должен и должен бросить.
источник
Зависит от того, что значит, что объект не найден.
Если это нормальное положение вещей, верните ноль. Это просто то, что может происходить время от времени, и вызывающие абоненты должны это проверить.
Если это ошибка, то выдается исключение, вызывающие абоненты должны решить, что делать с условием ошибки отсутствующего объекта.
В конечном итоге любой из них сработает, хотя большинство людей обычно считают хорошей практикой использовать Исключения только тогда, когда что-то, ну, в общем, Исключительное произошло.
источник
Вот еще пара предложений.
Если вы возвращаете коллекцию, избегайте возврата null, верните пустую коллекцию, что облегчает работу с перечислением без проверки на ноль.
Несколько API .NET используют шаблон параметра thrownOnError, который дает вызывающей стороне выбор, является ли это действительно исключительной ситуацией или нет, если объект не найден. Type.GetType является примером этого. Другим распространенным шаблоном с BCL является шаблон TryGet, в котором возвращается логическое значение, а значение передается через выходной параметр.
Вы можете также рассмотреть шаблон Null Object в некоторых обстоятельствах, которые могут быть по умолчанию или версией без поведения. Ключ заключается в том, чтобы избежать нулевых проверок по всей базе кода. Смотрите здесь для получения дополнительной информации http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx
источник
В некоторые функции я добавляю параметр:
True означает бросок, false означает возвращение некоторого возвращаемого значения ошибки. Таким образом, тот, кто использует эту функцию, имеет обе опции. Значение по умолчанию должно быть истинным для тех, кто забывает об обработке ошибок.
источник
Возврат null вместо выдачи исключения и четкое документирование возможности нулевого возвращаемого значения в документации API. Если вызывающий код не соблюдает API и проверяет нулевой регистр, он, скорее всего, в любом случае приведет к некоторому «исключению нулевого указателя» :)
В C ++ я могу представить 3 различных варианта настройки метода, который находит объект.
Вариант А
Вернуть ноль, когда объект не может быть найден. Красиво и просто. Я бы пошел с этим. Альтернативные подходы ниже для людей, которые не ненавидят out-params.
Вариант Б
Передайте ссылку на переменную, которая будет получать объект. Метод выдает исключение, когда объект не может быть найден. Это соглашение, вероятно, будет более подходящим, если на самом деле не ожидается, что объект не будет найден - поэтому вы бросаете исключение, чтобы указать, что это неожиданный случай.
Вариант С
Метод возвращает false, когда объект не может быть найден. Преимущество этого варианта перед А заключается в том, что вы можете проверить наличие ошибки за один четкий шаг:
источник
ссылаясь только на случай, когда null не считается исключительным поведением, я определенно являюсь для метода try, это ясно, нет необходимости «читать книгу» или «смотреть, прежде чем прыгнуть», как было сказано здесь
так в основном:
а это значит, что код пользователя тоже будет понятен
источник
Если для клиентского кода важно знать разницу между найденным и не найденным, и предполагается, что это обычное поведение, то лучше вернуть ноль. Клиентский код может затем решить, что делать.
источник
Обычно он должен возвращать ноль. Код, вызывающий метод, должен решить, выдавать ли исключение или пытаться что-то еще.
источник
Или верните опцию
Опция - это, по сути, контейнерный класс, который заставляет клиента обрабатывать стенды. У Scala есть такая концепция, посмотрите, это API.
Затем у вас есть методы, такие как T getOrElse (T valueIfNull) для этого объекта, которые либо возвращают найденный объект, либо альтернативу, указанную клиентом.
источник
Предпочитаю возвращать ноль -
Если вызывающая сторона использует его без проверки, исключение происходит в любом случае.
Если абонент не реально использовать его, не облагают его
try
/catch
блокисточник
К сожалению, JDK несовместим, если вы пытаетесь получить доступ к несуществующему ключу в комплекте ресурсов, вы получаете исключение not found, а когда вы запрашиваете значение из карты, вы получаете нулевое значение, если оно не существует. Поэтому я бы изменил ответ победителя следующим образом: если найденное значение может быть нулевым, то возбудить исключение, если оно не найдено, в противном случае вернуть нулевое значение. Так что следуйте правилу с одним исключением, если вам нужно знать, почему значение не найдено, всегда вызывайте исключение, или ..
источник
До тех пор, пока он должен возвращать ссылку на объект, возвращать NULL должно быть хорошо.
Однако, если он возвращает всю кровавую вещь (как в C ++, если вы делаете: «return blah;» вместо «return & blah;» (или «blah» - указатель)), то вы не можете вернуть NULL, потому что это не типа «объект». В этом случае я бы выбрал проблему или выдал пустой объект, для которого не установлен флаг успеха.
источник
Не думайте, что кто-то упомянул о накладных расходах при обработке исключений - для загрузки и обработки исключения требуются дополнительные ресурсы, поэтому, если только это не является действительным событием уничтожения приложения или остановки процесса (продвижение вперед принесет больше вреда, чем пользы), я бы предпочел передать обратно Значение вызывающей среды можно интерпретировать так, как она считает нужным.
источник
Я согласен с тем, что кажется консенсусом здесь (верните ноль, если «не найдено» - нормальный возможный результат, или выведите исключение, если семантика ситуации требует, чтобы объект всегда находился).
Однако есть и третья возможность, которая может иметь смысл в зависимости от вашей конкретной ситуации. Ваш метод может вернуть объект по умолчанию некоторого вида в состоянии «не найден», что позволяет вызывающему коду быть уверенным, что он всегда получит действительный объект без необходимости проверки на нуль или перехвата исключений.
источник
Возвратите ноль, исключения являются именно этим: то, что ваш код делает, что не ожидается.
источник
Исключения должны быть исключительными . Вернуть ноль, если допустимо вернуть ноль .
источник
Если метод возвращает коллекцию, верните пустую коллекцию (как сказано выше). Но, пожалуйста, не Collections.EMPTY_LIST или что-то подобное! (в случае Java)
Если метод получает один объект, у вас есть несколько вариантов.
Будьте осторожны, если вы решили вернуть ноль. Если вы не единственный программист в проекте, вы получите NullPointerExceptions (на Java или на других языках) во время выполнения! Так что не возвращайте нули, которые не проверяются во время компиляции.
источник
null
. См. Голосование с наибольшим количеством голосов для получения дополнительной информации.Если вы используете библиотеку или другой класс, который выдает исключение, вы должны выбросить его заново . Вот пример. Example2.java похож на библиотеку, а Example.java использует его объект. Main.java является примером для обработки этого исключения. Вы должны показать осмысленное сообщение и (при необходимости) трассировку стека пользователю на вызывающей стороне.
Main.java
Example.java
Example2.java
источник
Это действительно зависит от того, ожидаете ли вы найти объект или нет. Если вы следуете школе мысли, что исключения должны использоваться для обозначения чего-то, ну, а, конечно, произошло исключение:
В противном случае верните ноль.
источник